一、mutex
mutex: 提供最基本的lock和unlock
lock_guard<mutex> locker(mtx):离开作用域,自动析构的时候会释放锁,省了一句话。其次,提供exception safety。出现异常的时候也能释放锁。
unique_lock<mutex> locker(mtex):作用和lock_guard一样的。多了一个灵活性,在作用域内可以自由lock和unlock,而lock_guard不支持。所以condition_variable只能采用unique_lock或者mutex。
整体上,最简单就用直接用mutex是没问题的,主要mutex内的东西都是最简短的代码,毕竟不能并发。
如果代码对稳定性要求高,考虑到exception safe,就后两个混用。
如果用到condition_variable,只用最后一个。
二、condition_variable
主要用wait方法,有阻塞时间限制再用wait_for或者wait_until
只能用unique_lock, condition_variable_any也支持普通mutex。
wait或wait_for的逻辑是这样的:
1.释放当前锁(unique_lock, 或者mutex)
2.阻塞等待notify
3.阻塞超过时间,跳到5
4.收到notify信号,跳到5
5.阻塞等待锁
6.获取锁成功,语句结束
一般情况会写成这样while(flag==true)conditon.wait(); 因为被notify和获取锁的以后,有些场景中可能条件又不满足了,这样可以保证一定是满足判断条件的。
#include <thread>
#include <mutex>
#include <condition_variable>
class TestThread
{
public:
void start(){
thread t(std::bind(&TestThread::run,this));
t.detach();
}
void run(){
cout << "test thread waits. id:" << std::this_thread::get_id()<<endl;
waitToRace();
}
void waitToRace(){
unique_lock<mutex> locker(mtx);
condition.wait(locker);
cout << "test thread is racing. id:" << std::this_thread::get_id() << endl;
}
};
void go(){
int k = 10;
while(k--){
cout << "go one:" << std::this_thread::get_id() << endl;;
condition.notify_one();
this_thread::sleep_for(chrono::milliseconds(1500));
}
}
int main(void)
{
cout << "main thread id:" << std::this_thread::get_id() << endl;
for (int i = 0; i < 10; i++){
TestThread testThread;
testThread.start();
}
go();
getchar();
return 0;
}
本文深入解析并发编程中互斥锁和条件变量的使用,包括mutex、lock_guard、unique_lock、condition_variable的基本操作及应用场景,通过代码实例展示如何在多线程环境下实现高效同步。
2242

被折叠的 条评论
为什么被折叠?



