操作系统课设
1、实验目的
(1)回顾操作系统进程、线程的有关概念,针对经典的同步、互斥、死锁与饥饿问题进行并发程序设计。
(2)了解互斥体对象,利用互斥与同步操作编写读者-写者问题的并发程序,加深对 P (即 semWait)、V(即 semSignal)原语以及利用 P、V 原语进行进程间同步与互斥操作的理解。
(3)理解 Linux 支持的信息量机制,利用 IPC 的信号量系统调用编程实现哲学家进餐问题。
2、设计任务:
(1)读者-写者问题的并发程序设计
(2)哲学家进餐问题的并发程序设计以上两个任务任选一个完成即可。
3、背景知识
(1)相关并发控制的 Windows API 函数请参考实验五。
(2)UINX/Linux 系统把信号量、消息队列和共享资源统称为进程间通信资源(IPC resource)。提供给用户的 IPC 资源是通过一组系统调用实现的。任务二中将使用 IPC 中提供的 semget(),semop (),及 semctl()等信号量系统调用,它们的简介请查询实验四的背景知识部分,具体如何使用请自行进一步查询有关资料。
4、实验内容和要求
(1)读者-写者问题的并发程序设计
根据实验五中所熟悉的 P、V 原语对应的实际 Windows API 函数,并参考教材中读者-写者问题的算法原理,尝试利用 Windows API 函数实现第一类读者-写者问题(读者优先)。
5、描述
emmmmm,因为这道题的代码如果看其他大佬的博客实在是不好改,所以我和老师说,我想写写者优先,老师表很赞同(233333),所以我的代码是写者优先。总的来说,写者优先和读者优先其实差不多,主要是要理解信号量是如何控制进程之间的同步以及进程内的互斥,这些其实都不算很难,加油叭,后来者。
6、代码
#include<windows.h>
#include <iostream>
#include<stdio.h>
#define MAX_READER_NUM 512
#define READER_NUM 2
#define WRITER_NUM 3
#define MOD 100
using namespace std;
int readcount=0;
int writecount=0;
HANDLE a;//写着优先读者的第1个互斥量
HANDLE b;//写着优先读者的第2个互斥量,同时也是写者让读者阻塞的信号量
HANDLE c;//写着优先读者的第3个互斥量
HANDLE y;//这个可以参考书上的伪代码理解
HANDLE middle;//实现读者写者互斥的信号量
HANDLE input;//这是将输出作为临界资源,这样有利于防止两个进程同时输出,造成本应该换行的输出在一行输出,此外这是读者的输出,命名不规范
HANDLE output;//同Input,这是写者的输出
DWORD WINAPI reader(LPVOID);//调用windowsAPI函数
DWORD WINAPI writer(LPVOID);
bool p_continue=true;
int test=0;
int process_write_num=0;//统计每个进程执行的次数
int process_read_num=0;
int main()
{
a = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
b = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
c = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
input = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
output=CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
middle = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
y=CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
HANDLE hThreads[READER_NUM + WRITER_NUM];
DWORD readerID[READER_NUM];
DWORD writerID[WRITER_NUM];
for(int i=0;i<WRITER_NUM;i++)
{
hThreads[i]=CreateThread(NULL,0,writer,NULL,0,&writerID[i]);//创建写者进程
if(hThreads[i]==NULL)
return -1;
}
for(int i=0;i<READER_NUM;i++)
{
hThreads[i]=CreateThread(NULL,0,reader,NULL,0,&readerID[i]);//创建读者线程
if(hThreads[i]==NULL)
return -1;
}
while(p_continue)//当输入空格的时候结束程序
{
if(getchar())
{
p_continue = false;
printf("在这个过程中读者进程的数量:%d\n",process_read_num);
printf("在这个过程中写者进程的数量:%d\n",process_write_num);
}
}
return 0;
}
void READUNIT()
{
WaitForSingleObject(input,INFINITE);//p操作
process_read_num++;
cout<<"一个读者进程开始读:";
cout<<test<<endl;
ReleaseSemaphore(input,1,NULL);//v操作
}
void WRITEUNIT()
{
process_write_num++;
cout<<"一个写者开始写:";
test=(test+1)%MOD;
cout<<test<<endl;
ReleaseSemaphore(output,1,NULL);
}
DWORD WINAPI writer(LPVOID lpPara)
{
while(p_continue)
{
WaitForSingleObject(y,INFINITE);
writecount++;
if(writecount==1)
WaitForSingleObject(b,INFINITE);
ReleaseSemaphore(y,1,NULL);
WaitForSingleObject(middle,INFINITE);
WRITEUNIT();
ReleaseSemaphore(middle,1,NULL);
WaitForSingleObject(y,INFINITE);
writecount--;
if(writecount==0)
ReleaseSemaphore(b,1,NULL);
ReleaseSemaphore(y,1,NULL);
Sleep(300);
}
return 0;
}
DWORD WINAPI reader(LPVOID lpParar)
{
while(p_continue)
{
WaitForSingleObject(a,INFINITE);
WaitForSingleObject(b,INFINITE);
WaitForSingleObject(c,INFINITE);
readcount++;
if(readcount==1)
WaitForSingleObject(middle,INFINITE);
ReleaseSemaphore(a,1,NULL);
ReleaseSemaphore(b,1,NULL);
ReleaseSemaphore(c,1,NULL);
READUNIT();
WaitForSingleObject(c,INFINITE);
readcount--;
if(readcount==0)
ReleaseSemaphore(middle,1,NULL);
ReleaseSemaphore(c,1,NULL);
Sleep(200);
}
return 0;
}
总的来说的话,emmmmm,还是看别人的看的太多了,几乎是模拟别人写的代码,23333,但是课设嘛,总有很多不会的,不建议大家抄,但是可以在别人的基础上做更新(当然不是简单的更换输出和变量名,23333),好啦,就到这叭,代码看不懂的地方可以在下方留言哈。