众所周知C++11并没有给我们提供什么好用一点的并发组件,委员会非常慷慨地给我们留了一堆空白,直到C++20才把这些并发组件给补上。
这里用条件变量和mutex实现一个非常简单的信号量。
首先我们要知道什么是信号量:
信号量是一个持有一个计数器cnt,并且支持 up 和 down 操作的同步器。
up增加cnt变量,并在cnt变量大于0的时候唤醒一个线程,并不会去堵塞线程。
down操作则是反着来,down操作减少cnt变量,并在cnt变量小于0的时候堵塞执行down操作的线程。
class Semaphore{
int cnt;
void up(){}
void down(){}
}
于是我们写的信号量的一个框架就出来了。
首先要注意到的一点是,由于up和down操作都是要修改cnt,而在多线程程序中,只要修改可变变量就必定要加锁,所以我们的up和down操作都需要加锁,这里使用最简单直白的方法加锁。
std::mutex mtx;
std::unique_lock<std::mutex> lock{mtx}
唤醒线程和阻塞线程我们这里就选用条件变量,因为条件变量的wait 和notify_one非常符合要求。
首先是up操作
void Semaphore::up(){
std::unique_lock<std::mutex> lock{mtx};
cnt++;
cv.notify_one();
}
其次是down操作
void Semaphore::down(){
std::unique_lock<std::mutex> lock{mtx};
cv.wait(lock, [this]{return cnt > 0;});
cnt--;
}
网友评论