//mutex condition_variable 自定义信号量的使用
#include <iostream>
#include <thread>
#include <mutex>
#include <windows.h>
#include <condition_variable>
#include <queue>
using namespace std;
//1. 信号量使用 一个线程打印A 一个线程打印B
namespace jack {
class semaphore {
public:semaphore(const int& init = 1):count(init),
wakeups(0){}
void wait() {
unique_lock<mutex> lock(mtx);
if (--count < 0) {
condition.wait(lock, [&]()->bool {return wakeups > 0; });
--wakeups;
}
}
void post() {
unique_lock<mutex> lock(mtx);
if (++count <= 0) {
++wakeups;
condition.notify_one();
}
}
private:
int count;
int wakeups;
mutex mtx;
condition_variable condition;
};
}
jack::semaphore sem(1);
jack::semaphore sA(1);
jack::semaphore sB(0);
void PrintA(int i)
{
while (true)
{
//死锁
/*lock_guard<mutex> guard1(mtxA);
cout << "a" << endl;
this_thread::sleep_for(chrono::milliseconds(100));
lock_guard<mutex> guard2(mtxB);*/
//锁无法解决这个问题
sA.wait();
sem.wait();
cout << "a" << endl;
this_thread::sleep_for(chrono::milliseconds(100));
sem.post();
sB.post();
}
}
void PrintB(int i)
{
while (true)
{
//死锁
/*lock_guard<mutex> guard1(mtxB);
cout << "b" << endl;
this_thread::sleep_for(chrono::milliseconds(100));
lock_guard<mutex> guard2(mtxA);*/
sB.wait();
sem.wait();
cout << "b" << endl;
this_thread::sleep_for(chrono::milliseconds(100));
sem.post();
sA.post();
}
}
//2.生产者消费者模型
class Queue
{
public:
Queue()
{
}
void put(int val)
{
//lock_guard<mutex> guard(mtx);
unique_lock<mutex> lcx(mtx);
if (!_qq.empty())
{
cv.wait(lcx);
}
_qq.push(val);
cv.notify_all();
cout << "生产者生产物品" << val << endl;
}
void pop()
{
//lock_guard<mutex> guard(mtx);
unique_lock<mutex> lcx(mtx);
if (_qq.empty())
{
cv.wait(lcx);
}
cout << "消费者消费物品" << _qq.front() << endl;
_qq.pop();
cv.notify_all();
}
private:
queue<int> _qq;
mutex mtx;
condition_variable cv;
};
void producer(Queue* q)
{
while (1)
{
q->put(1);
Sleep(100);
}
}
void consumer(Queue* q)
{
while (1)
{
q->pop();
Sleep(100);
}
}
int main()
{
Queue q;
thread t1(producer, &q);
thread t2(consumer, &q);
t1.join();
t2.join();
}