#include <iostream>
#include <condition_variable>
#include <thread>
#include <queue>

using namespace std;
#define LOOP_TIMES 50

void test1() {
	int res = 0, fake_count = 0;
	mutex mtx;
	condition_variable cv;
	queue<int> mq;
	thread t1([&]() {
		for (int i = 0; i < LOOP_TIMES * 2; i++) {
			this_thread::sleep_for(chrono::milliseconds(i));
			//unique_lock<mutex> lock(mtx);
			mq.push(i / 4);
			//std::cout << "notify one " << i << " " << res << "\n";
			cv.notify_all();
			res = res + 1;
		}
	});
	auto consume_fn = [&]() {
		for (int i = 0; i < LOOP_TIMES; i++) {
			this_thread::sleep_for(chrono::milliseconds(i));
			unique_lock<mutex> lock(mtx);
			while (mq.empty()) {
				fake_count++;
				//std::cout << "wait one " << i << " " << res  << " " << fake_count << "\n";
				cv.wait(lock);
			}
			//std::cout << "handle one " << i << " " << res << "\n";
			mq.pop();
		}
	};
	thread t2(consume_fn);
	thread t3(consume_fn);
	t1.join();
	t2.join();
	t3.join();
	std::cout << "test3:: res:: " << res << " fake_count:: " << fake_count << " condition_variable:: size " << sizeof(cv) << endl;
}
int main() {
	test1();
	/*
	条件变量：
		wait(unique_lock<mutex>);
			unlock 解锁
			wait cond 等待其他线程唤醒
			lock  上锁（可能会阻塞）
		notify_one 唤醒一个线程
		虚假唤醒，条件变量只负责通知线程抢夺资源，并不保证一定能分配（抢到）资源
	*/
	return 1;
}