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;
							 | 
						|||
| 
								 | 
							
								}
							 |