56 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#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;
 | 
						|
} |