线程同步机制
线程之间共享代码、资源、进程(内存)空间、打开文件等。
线程同步机制
互斥锁
互斥锁本质是一个全局变量,其值为0时表示没锁,可以对其进行上锁(+1),而且上锁的操作由硬件和操作系统保证是原子操作,所以不存在两个线程同时上一把锁。其值为1时表示上锁,线程再进行lock
操作会阻塞自己,并在互斥锁队列里等待其解锁。被lock()和unlock()包围的代码称之为临界区(critical section)
mutex mxt;
void f(){
mxt.lock()
//critical seciotn
mxt.unlock()
}
thread t1(f);
thread t2(f);
这样就保证同时只有一个线程在访问临界区。
信号量
允许值大于1的互斥锁,down()
减1,up()
加1,信号量为0时阻塞,大于0被唤醒。
条件变量
也是一个全局变量,作用是使线程阻塞直到等待一个条件成立再继续运行。条件变量是一个队列,线程检测到条件不满足会将自己加入(wait()
)这个队列里等待被唤醒。另外的线程在改变条件的时候也可以唤醒(signal()
)队列中的一个或全部线程。注意这个唤醒操作是将线程从条件变量的队列里出列,进入互斥锁的阻塞队列竞争互斥锁,而不是唤醒就直接开始执行下边的代码。没有被唤醒的线程会继续在条件变量的队列中,即使互斥锁被释放也不会去获得锁。
一个典型的条件变量使用:
std::mutex mtx;
std::condition_variable_any cond;
void child() {
mtx.lock();
while(not some condiiton) //使用while为了避免“虚假唤醒”
cond.wait(mtx); // 释放锁,加入条件变量的阻塞队列
//被唤醒,获得锁,继续执行
// do somthing
mtx.unlock();
}
void parent() {
mtx.lock();
//do somthing,条件满足
cond.notify_one(); // 唤醒一个线程
cond.notify_all(); // 唤醒全部线程
mtx.unlock();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】