67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								#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;
							 | 
						|||
| 
								 | 
							
								}
							 |