1、Mutex信号量,
简单方便.lock_guard构造时调用T的lock,析构时调用unlock。没有其它的操作了。同一个线程调用多次也会导致锁定。
void CThreadLockTest::LockMutext()
{
lock_guard<mutex> guard(some_mutex_);
int new_value = 10;
some_list_.push_back(new_value);
}
2、共享信号量
目前C++标准不支持,boost才支持。需要使用shared_mutex作为信号变量
shared_lock即为共享锁,在lock时候会增加判断中会判断。可以多次使用只读锁。
unique_lock即为独占锁。
void CThreadLockTest::LockSharedMutex()
{
boost::shared_mutex entry_mutext;
// 共享锁,只读可以用多次
boost::shared_lock<boost::shared_mutex> lk1(entry_mutext);。最后调用的是shared_mutex的lock_shared接口
boost::shared_lock<boost::shared_mutex> lk2(entry_mutext);
// 独占锁
boost::unique_lock<boost::shared_mutex> lk3(entry_mutext);。最后调用的是shared_mutex的lock接口
}
3、递归信号量
可以支持同一个线程多次锁定,当然也需要多次释放
mute都是继承自mutexbase,里面有个flag标记,递归锁就是默认构造时将flag设置为了0x100
内部会判断同一个线程id就可以锁多次。不同线程id的话语普通锁一样。不推荐使用
void CThreadLockTest::LockRecursiveMuex()
{
std::lock_guard<std::recursive_mutex> lk1(recusive_mutex_1);
std::lock_guard<std::recursive_mutex> lk2(recusive_mutex_1);
}
4、对应的锁
lock_guard:最简单,构造锁定,析构释放。构造函数中也有参数表示是否立即锁定参数
unique_lock:增加了lock,unlock接口,更加灵活。同时也增加了一个参数表示自己是否拥有该锁的所有权。
boost::shared_lock:配合shared_mutex使用
5、只执行一次接口。可以在单键等情况下使用,线程安全
once_flag:只执行一次标记
call_once:只执行一次接口
std::shared_ptr<CTest> resource_ptr;
std::once_flag resource_flag;
void InitResource(int)
{
resource_ptr.reset(new CTest);
}
void CThreadLockTest::CallOnceFunction()
{
// 成员函数的调用
std::call_once(resource_flag, &CThreadLockTest::LockMutext, this);
// 全局函数的调用,并且支持参数
std::call_once(resource_flag, InitResource, 10);
}
6、避免死锁
同时锁定多把锁,要不全部锁定成功,要不失败。防止两把锁的拥有者属于不同线程导致互相等待
void CThreadLockTest::LockMoreMutex()
{
// 同时锁两个mutext
std::lock(some_mutex_, some_mutext_2_);
// 再赋值给lock_guard只是为了方便析构释放。
// 使用adopt_lock作为第二个参数是希望guard1不要再去锁了,因为std::lock已经有锁了
lock_guard<mutex> guard1(some_mutex_, std::adopt_lock);
lock_guard<mutex> guard2(some_mutext_2_, std::adopt_lock);
int new_value = 10;
some_list_.push_back(new_value);
some_list2_.push_back(new_value);
}
也可以自己实现,对锁增加一个参数:优先级,与lock思想一样,锁定了高优先级再去锁定低优先级能成功,反之则失败
7、线程局部变量
vs2013也不支持。2015才支持