多線程 std::lock 當要同時操作2個對象時,就需要同時鎖定這2個對象,而不是先鎖定一個,然後再鎖定另一個。同時鎖定多個對象的方法:std::lock(對象1.鎖,對象2.鎖...) 額外說明:lock_guard\ lock_a(d1.m, std::adopt_lock); 上面這句是為了 ...
多線程 std::lock
當要同時操作2個對象時,就需要同時鎖定這2個對象,而不是先鎖定一個,然後再鎖定另一個。同時鎖定多個對象的方法:std::lock(對象1.鎖,對象2.鎖...)
額外說明:lock_guard<mutex> lock_a(d1.m, std::adopt_lock);
上面這句是為瞭解開std::lock的鎖。
參數std::adopt_lock的作用:告訴lock_guard,d1.m已經被上鎖了,你不要再去鎖它了,沿用它原來的鎖就好。
例子:
#include <list>
#include <iostream>
#include <mutex>
#include <algorithm>
#include <thread>
#include <unistd.h>
using namespace std;
class data_protect;
void swap(data_protect& , data_protect& );
//是線程安全的
class data_protect{
friend void swap(data_protect& , data_protect& );
private:
list<int> alist{1,2};
mutex m;
public:
void add_list(int val){
//操作雙向鏈表時,加鎖了
lock_guard<mutex> g(m);
alist.push_back(val);
}
bool contains(int val){
//操作雙向鏈表時,加鎖了
lock_guard<mutex> g(m);
return find(alist.begin(), alist.end(), val) != alist.end();
}
};
void swap(data_protect& d1, data_protect& d2){
std::lock(d1.m, d2.m);
//造成死鎖
//d1.add_list(11);
lock_guard<mutex> lock_a(d1.m, std::adopt_lock);
lock_guard<mutex> lock_b(d2.m, std::adopt_lock);
swap(d1.alist, d2.alist);
}
int main(){
data_protect d1, d2;
swap(d1, d2);
}