转载:c++11用互斥和条件变量实现信号量 - zhangbaochong - 博客园 (cnblogs.com)
重点:
1.主要的思路就是一个人在执行的时候,其他人全部在等待,等这个人执行完了,就唤醒其他人。
#include <ctime>
#include <atomic>
using namespace std;
class semaphore
{
public:
semaphore(int value = 1) :count(value) {}
void wait()
{
unique_lock<mutex> lck(mtk);
if (--count < 0)//资源不足挂起线程
{
cout << count << endl;
cv.wait(lck);
}
}
void signal()
{
unique_lock<mutex> lck(mtk);
if (++count <= 0)//有线程挂起,唤醒一个
{
cout << count << endl;
cv.notify_one();
}
}
private:
int count;
mutex mtk;
condition_variable cv;
};
semaphore plate(1), apple(0), orange(0);
void father()
{
while (true)
{
plate.wait();
cout << "往盘中放一个苹果" << endl;
apple.signal();
}
}
void mother()
{
while (true)
{
plate.wait();
cout << "往盘中放一个橘子" << endl;
orange.signal();
}
}
void son()
{
while (true)
{
apple.wait();
cout << "儿子吃苹果" << endl;
plate.signal();
}
}
void daughter()
{
while (true)
{
orange.wait();
cout << "女儿吃橘子" << endl;
plate.signal();
}
}
int main()
{
thread f(father), m(mother), s(son), d(daughter);
f.join();
m.join();
s.join();
d.join();
return 0;
}
总结:
前面看错了,以为所有人共享count,其实每个人一个count,其中plate共享一个count,一开始,四个线程同时进入wait,但是女儿和儿子线程被锁住,因为他们的count减1后小于0,而母亲和父亲共用的count一开始是1,所以要么父亲先执行,要么母亲先执行,然后另一个被锁住因为count=-1。假设父亲先执行,母亲则被锁住,然后父亲唤醒儿子的线程,然后父亲继续wait,这个时候父亲的count是-2,但是儿子执行plate.signle,则要么唤醒父亲要么唤醒母亲,因为父亲母亲同时被锁住,假如母亲被唤醒,则母亲执行女儿的signle,然后循环下去。
|