如何理解互斥锁、条件锁、读写锁以及自旋锁?

本文详细介绍了互斥锁、条件变量、读写锁和自旋锁四种锁机制,分别阐述了它们的工作原理、优缺点以及在C++和pthread中的使用。互斥锁是最常见的同步方式,条件变量是线程间的通信机制,读写锁适合读多写少的场景,而自旋锁则避免了线程上下文切换的开销,但可能导致CPU资源浪费。在具体使用中,应根据场景选择合适的锁类型。
摘要由CSDN通过智能技术生成

锁是一个常见的同步概念,我们都听说过加锁(lock)或者解锁(unlock),当然学术一点地说法是获取(acquire)和释放(release)。

恰好pthread包含这几种锁的API,而C++11只包含其中的部分。接下来我将通过pthread的API来展开回答。

mutex(互斥量)

mutex(mutual exclusive)即互斥量(互斥体)。也便是常说的互斥锁。
尽管名称不含lock,但是称之为锁,也是没有太大问题的。mutex无疑是最常见的多线程同步方式。其思想简单粗暴,多线程共享一个互斥量,然后线程之间去竞争。得到锁的线程可以进入临界区执行代码。

// 声明一个互斥量    
pthread_mutex_t mtx;
// 初始化 
pthread_mutex_init(&mtx, NULL);
// 加锁  
pthread_mutex_lock(&mtx);
// 解锁 
pthread_mutex_unlock(&mtx);
// 销毁
pthread_mutex_destroy(&mtx); 

mutex是睡眠等待(sleep waiting)类型的锁,当线程抢互斥锁失败的时候,线程会陷入休眠。优点就是节省CPU资源,缺点就是休眠唤醒会消耗一点时间。另外自从Linux 2.6版以后,mutex完全用futex的API实现了,内部系统调用的开销大大减小。

值得一提的是,pthread的锁一般都有一个trylock的函数,比如对于互斥量:

ret = pthread_mutex_trylock(&mtx);
if (0 == ret) { // 加锁成功
    ... 
    pthread_mutex_unlock(&mtx);
} else if(EBUSY == ret){ // 锁正在被使用;
    ... 
}

pthread_mutex_trylock用于以非阻塞的模式来请求互斥量。就好比各种IO函数都有一个noblock的模式一样,对于加锁这件事也有类似的非阻塞模式。

当线程尝试加锁时,如果锁已经被其他线程锁定,该线程就会阻塞住,直到能成功acquire。但有时候我们不希望这样。pthread_mutex_trylock在被其他线程锁定时,会返回特殊错误码。加锁成返回0,仅当成功但时候,我们才能解锁在后面进行解锁操作!

C++11开始引入了多线程库<thread>,其中也包含了互斥锁的API:std::mutex 。

此外,依据同一线程是否能多次加锁,把互斥量又分为如下两类:

  • 是&#x
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

果冻虾仁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值