#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <semaphore>
using namespace std;
#define LOOP_TIMES 1

void test1() {
	int res = 0;
	binary_semaphore bs(0);
	thread t1([&]() {
		this_thread::sleep_for(chrono::milliseconds(1000));
		res = 12;
		bs.release();
	});
	t1.detach();
	bs.acquire();
	std::cout << "test1:: res "<< res << endl;
}
void test2() {
	int res = 0;
	counting_semaphore<> cs(0);
	queue<int> mq;
	mutex mtx;
	auto p = [&]() {
		for (int i = 0; i < LOOP_TIMES * 2; i++) {
			{	//保证res 与 mq 的修改线程安全
				std::this_thread::sleep_for(std::chrono::milliseconds(1000));
				lock_guard<mutex> lock(mtx);
				mq.push(i / 2);
				res = res + 1;
			}
			cs.release();
		}
		std::cout << "product end " << res << "\n";
	};
	auto c = [&](int id) {
		for (int i = 0; i < LOOP_TIMES; i++) {
			cs.acquire();//这里不存在虚假唤醒，一定能抢到资源，只是资源顺序不确定
			{
				lock_guard<mutex> lock(mtx);
				mq.pop();
				res = res - 1;
			}
		}
		std::cout << "consume end " << id << " -> " << res << "\n";
	};
	thread t1(p);
	thread t2(c, 1);
	thread t3(c, 2);
	t1.join();
	t2.join();
	t3.join();
	std::cout << "test1:: res " << res << " mq " << mq.size() << endl;
}
int main() {
	test1();
	test2();
	//信号量可以实现一批资源的分配
	//信号量可由条件变量与锁实现
	//信号量封装后可以实现chanel效果
	std::cout << "binary_semaphore size:: " << sizeof(binary_semaphore) <<
		" counting_semaphore<3> size:: " << sizeof(counting_semaphore<3>)<<
		" counting_semaphore<10> size:: " << sizeof(counting_semaphore<10>) << endl;
	return 1;
}