本文主要是介绍【C++代码】信号量Semaphore,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
转载:https://blog.csdn.net/weixin_43222324/article/details/108929266
C++代码如下:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>using namespace std; // 如果不写这句,后面的mutex、cout等前面都要加std::class Semaphore
{
private:int count;mutex m;condition_variable cv;
public:Semaphore(int count_) : count(count_) {}// p操作:count 减1,如果count<0,则资源不足,把线程放入阻塞队列 void p() {unique_lock<mutex> loc(m);// if (--count < 0) {cv.wait(loc); }}// v操作:count加1,如果 count <= 0 ,则有线程阻塞,在阻塞队列里唤醒一个线程void v() {unique_lock<mutex> loc(m); if (++count <= 0) {cv.notify_one(); }}
};
如何使用信号量?
总结起来就是一句话:先v后p
在期望先执行的代码后执行v操作,在期望后执行的代码前执行p操作。
举个例子
不管两个线程谁先执行,我们都希望让线程先打印first,后打印second,如何让这两个线程按序打印呢?
按照前面说的,我们只需要在first函数(期望先执行的代码)里写上v操作,在second函数(期望后执行的代码)里写上p操作,就能实现两个线程的同步了。
Semaphore s(0); // 信号量初始化count为0void first() {cout << "first" << endl; // 期望先执行的代码s.v(); // 期望先执行的代码 后面 写上v
}void second() {s.p(); // 期望后执行的代码 前面写上pcout << "second" << endl; // 期望后执行的代码
}int main() { thread t2(second);thread t1(first);t2.detach();t1.detach(); this_thread::sleep_for(chrono::milliseconds(500));
}
我们可以来分析一下上面的程序:
- 情况1: 如果先执行t1线程,在打印完first后,信号量s中的count加1,此时count=1。然后执行到t2线程,此时count减1,count=0,但并未<0,因此不会被阻塞,顺利打印second。
- 情况2: 如果先执行t2线程,信号量s中的count减1,此时count=-1,<0,线程t2被阻塞。然后t1线程打印first,信号量s中的count加1,此时count=0,满足<=0条件,阻塞队列中的t2会被唤醒,继续执行,打印second
这篇关于【C++代码】信号量Semaphore的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!