code link: 欢迎star
文章目录
1. 实验目的
探索、理解并掌握操作系统同步机制的应用编程方法,针对典型的同步问题,构建基于Windows(或 Linux)操作系统同步机制的解决方案。
2. 实验内容
了解、熟悉和运用 Windows(或 Linux)操作系统同步机制及编程方法,针对典型的同步问题,譬如生产者-消费者问题、读者优先的读者-写者问题、写者优先的读者-写者问题、读者数限定的读者-写者问题、哲学家就餐问题等(任选四个即可),编程模拟实现相应问题的解决方案。
3. 实验要求
典型同步问题模拟处理编程功能设计要求为:运用 Windows(或 Linux)操作系统同步机制,从生产者-消费者问题、读者优先的读者-写者问题、写者优先的读者-写者问题、读者数限定的读者-写者问题、哲学家就餐问题等典型同步问题中选取四个同步问题,分析、设计和编程模拟实现相应问题的解决方案。
4. 实验思路
- 第一部分,生成者消费者问题。使用两个整型信号量empty和full,一个互斥控制量mutex。创建两个线程函数,read和write。这里参考了ppt上的代码,采用了一个nloop进行循环次数控制。
- 第二部分,读者优先的读者和写者问题。其中,读者可以并发执行,但是写者进程与其他进程互斥。Readcount计数变量也是临界资源,也要添加一个互斥变量,进行互斥访问。由于读写操作我们可以简化为往流中读写数据,我们可以直接使用一个string 的buffer进行读写,相比文件的读写更加快速,适用于实验的调试。
- 第三部分,写者优先的读者和写者问题。我们的目标是,写者优先,即需要有一个写者队列,注意写者仍要保持互斥,只要队列数大于0读者就不能进行;同时,读者要能进行并行读出且写者仍要互斥。相比第二部分,只要增加一个由写者队列数控制的开关即可。
- 第四部分,哲学家就餐问题。这里采用互斥信号量保证同时拿起两支筷子。同时设置一个最高nloop控制最多吃饭次数;将think和eat简化为交互内容输出,方便程序验证。
5. 实验内容
5.1. 相关环境介绍
操作系统:window 10 21H2
开发环境:Clion-2022.2.1-Windows
编译器:mwing-10.0
5.2. 生产者消费者问题
代码:
01:#define N 5
02:#define MAXNLOOP 30
03:
04:int in = 0;
05:int out = 0;
06:HANDLE WINAPI empty = CreateSemaphore(NULL, 10, 10, "empty");
07:HANDLE WINAPI full = CreateSemaphore(NULL, 0, 10, "full");
08:HANDLE WINAPI mutex = CreateMutex(NULL, FALSE, "MutexToProtectCriticalResource");
09:
10:string buffer[N];
11:int nloop = 0;
12:DWORD WINAPI ThreadExecuteZZWProducer(LPVOID lpParameter){
13: int *pID = (int *)lpParameter;
14: string nextp = to_string(*pID) + " produced";
15: while(1){
16: WaitForSingleObject(empty, INFINITE);
17: WaitForSingleObject(mutex, INFINITE);
18: if(nloop>MAXNLOOP) break;
19: buffer[in] = nextp;
20: in = (in + 1) % N;
21: cout << "nloop " << nloop << " producer " << *pID << " has produced on the buffer " << in << "\n";
22: ++nloop;
23: ReleaseMutex(mutex);
24: ReleaseSemaphore(full, 1, NULL);
25:
26: }
27: return 0;
28:}
29:
30:DWORD WINAPI ThreadExecuteZZWConsumer(LPVOID lpParameter){
31: int *pID = (int*)lpParameter;
32: string nextp;
33: while(1){
34: WaitForSingleObject(full, INFINITE);
35: WaitForSingleObject(mutex, INFINITE);
36: if(nloop>MAXNLOOP) break;
37: nextp = buffer[out]