多线程锁相关

(备忘录)

一、互斥锁

#inclide < mutex >

 std::mutex m; m.lock(), m.unlock(),try_lock().

try_lock() 与 lock()的不同在于,try_lock() 在获取不到锁的时候不会阻塞,只会返回false表示拿不到锁

std::lock_guard<std::mutex> gm; 

std::unique_lock<std::mutex> um; 

mutex::scoped_lock 是 unique_lock的 typedef

lock_guard 和 unique_lock 都遵循RAII(资源访问即初始化:访问互斥资源的时候只需要初始化后就可以往下走,不用考虑释放锁)原则,但unique_lock 比 lock_guard 灵活,unique_lock 还额外提供了lock和unlock操作。unique_lock 和 lock_guard 都不可以拷贝复制,unique_lock 可move().

std::recursive_mutex:与mutex 的不同在于recursive_mutex可以在同一个线程中递归使用或说是嵌套使用,即里里外外每一层都可以使用,只要保证每一层的lock和unlock成对出现就行。

std::time_mutex:与mutex相比,多了2个时间相关的函数:try_lock_for(时间段) 和 try_lock_until(时间点) ,相当于mutex的try_lock(),但比try_lock()多个了个时间,try_lock()是拿不到锁直接返回,而try_lock_for(时间段) 和 try_lock_until(时间点) 是在传入的时间内拿不到锁则阻塞,超时后返回false。try_lock()相当于try_lock_for(0)。

二、条件锁

#include < condition_variable >

std::condition_variable(只和std::mutex一起工作) 和 std::condition_variable_any(符合类似互斥元的最低标准的任何东西一起工作)

条件变量解决的问题:在线程循环中等待时通过waitnotify来及时处理事件,如果没有这个机制的话wait的地方需要忙等或者sleep固定时长来不断的检测条件浪费CPU和浪费时间。

条件变量wait 需要传入unique_lock和一个返回布尔值的函数对象,为什么此处会需要这2个参数?首先线程要在wait出阻塞,那就需要在阻塞之后释放锁,这样其他使用该锁的地方才能继续工作,所以传入unique_lock在wait内部unlock。当notify之后wait还是被唤醒(中断后继续),使用unique_lock进行lock,然后继续执行。第2个参数是个函数,用来判断被唤醒之后是要直接返回还是继续往下走,true往下走,false直接返回,这样方便判断队列空不空,空的话就没必要继续往下走了。

std::mutex mut;
std::queue<data_chunk> data_queue;;
std::condition_variable data_cond;

std::lock_guard<std::mutex> lk(mut);
data_queue.push(data);
data_cond.notify_one();

void data_processing_thread()
{
while(true)
{
std::unique_lock<std::mutex> lk(mut); //这里使用unique_lock是为了后面方便解锁
data_cond.wait(lk,{[]return !data_queue.empty();});
data_chunk data=data_queue.front();
data_queue.pop();
lk.unlock();
process(data);
if(is_last_chunk(data))
break;
}
}

三、自旋锁

一个忙等的锁(busy-waiting),不断循环的去获取锁。

自旋锁是Linux内核里最常用的锁之一。

自旋锁的逻辑是,用自旋锁保护的临界区要足够小,而且临界区内是不能休眠的。所以当自旋锁加锁失败时,说明有其它的临界区正在执行中。由于自旋锁的临界区足够小且不会休眠,所以我们可以自旋忙等待其它临界区的退出,没必要去休眠,因为休眠要做一大堆操作。而忙等待的话,对方很快就会退出临界区,我们就可以很快地获得自旋锁了。

四、读写锁

C++ 17里已经引进了读写锁 std::shared_mutex , 其lock()即以写方式加锁, 其lock_shared()即以读方式加锁,但C++11还没有引入,只能使用boost里面的。

这是boost里面的锁,需要引入boost

#include <boost/thread/shared_mutex.cpp>
boost::shared_lock

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tangcpp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值