实验一进程同步.docx
《实验一进程同步.docx》由会员分享,可在线阅读,更多相关《实验一进程同步.docx(8页珍藏版)》请在冰豆网上搜索。
![实验一进程同步.docx](https://file1.bdocx.com/fileroot1/2022-11/28/92fba6e9-4d99-40b1-a6ed-d9e6870d8449/92fba6e9-4d99-40b1-a6ed-d9e6870d84491.gif)
实验一进程同步
操作系统实验一
进程同步算法的实现模拟
姓名:
陈振宇学号:
1010322319班级:
10网络三班
实验要求
(1)生产者—消费者问题。
Get、put二进程共用缓冲区s(大小为每次只存放一个记录)。
Get负责输入记录到缓冲区s,put负责把t中的记录取出打印。
(2)设计进程PCB结构和三种进程状态的队列,可以实现PCB队列的插入、删除、排序功能。
(3)设计各进程使用的信号灯,画出各进程的P、V
操作实现流程图;
(4)实现进程同步,完成记录的正常输出,要能够通过
程序运行表现出对缓冲区s的进行临界区互斥和进程
同步的思想(最好能记录或输出二个进程的实时状态和变化过程、二个进程队列的实时内容、几个缓冲区中实时内容,输出到屏幕上,这个过程同时记录在一个文本文件中);
(5)编程语言不限制,tc2.0,vc6.0,.net,java都可以。
实验过程
1.实验流程图
2•数据结构及算法描述
1)数据结构:
每个进程有一个进程控制块(PCB表示。
进程控制块可以
包含如下信息:
进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。
系统开辟了一个缓冲区,大小由buffersize指定。
程序中有三个链队列,一个链表。
一个就绪队列(ready),
两个等待队列:
生产者等待队列(producer);消费者队列
(consume!
)。
一个链表(over),用于收集已经运行结束的进程本程序通过函数模拟信号量的原子操作。
2)算法的文字描述:
大致由三个模块组成:
a.主程序(main):
i.创建信号量、共享内存并进行初始化
ii.创建生产者、消费者进程,生产者执行
pro_fun(),消费者执行con_fun()
iii.等待所有子进程的结束
iv.删除信号量、共享内存
b.生产者进程(pro_fun):
i.通过key获得信号量、共享内存的ID,将内存添加到自己的地址空间
ii.P(empty),P(mutex),Add(data),V(mutex),V(full)
iii.解除和共享内存的关联
c.消费者进程(con_fun):
i.通过key获得信号量、共享内存的ID,将内存添加到自己的地址空间
ii.P(full),P(mutex),Add(data),V(mutex),
V(empty)
iii.解除和共享内存的关联
d.循环队列部分:
加入数据:
info[end]=value;end=(end+1)%3;
取出数据:
temp=info[start];info[start]=0;(start=start+1)%3;returntemp;
3•生产者及消费者解决流程
同步问题:
P进程不能往满的缓冲区放产品,设置信号量empty,初值为0,用于指示空缓冲区数目。
V进程不能从空的缓冲区取产品,设置信号量
full,初值为0,用于知识满缓冲区数目。
解决流程:
P:
V:
Repeat:
repeat:
生产个产品;
p(full);
送产品到缓冲区;
从缓冲区取产品;
V(full);
V(empty);
P(empty);
消费产品
Untilfalse
untilfalse
生产者进程:
Ppoducei*
3finish
produeingf
■
■
position[
01:
3
Consiiwei*
4request
tocon&uiite1product
Ppoducep
2sendstheproduce
require・
Pp&ducep
2begin
taproduce
atposition
Producer
2finish
producing
■
■
positionL
11:
2
Producep
1fiendstheproduce
Fequipft・
Producer
1begfin
toproduce
atposition
Producer
1fin
produeingr
■
■
position[
21:
1
Gonsuwer
4begrinto
consune
1pi^oduct
Consutiier
4tinconsunincf
1:
position[
21:
-1
Consumer
4request
tocon^uite3produet
Consuiier
4he^finto
con^utie
3product
Con&umep
4finishconsult)ing
3:
positinnE
0i:
-1
Consumet*
4request
toconsuiite2ppoduct
ConGUtneF
4beginto
2pFGduct
Consunet*
4finishconsuming
2:
positian[
11:
T
Pressanykeytocontinue
4)实验结果
2
三.实验源代码
#includevwindows・h>
#includeviostream>
constunsignedshortSIZE_OF_BUFFER=10缓中区长度unsignedshortProductID=0;//产品号
unsignedshortConsumeID=0;//将被消耗的产品号
unsignedshortin=0;
unsignedshortout=0;
intg_buffer[SIZE_OF_BUFFER];boolg_continue=true;HANDLEg_hMutex;
HANDLEg_hFullSemaphore;
HANDLEg_hEmptySemaphore;
DWORDWINAPIProducer(LPVOID);//生产者线程
DWORDWINAPIConsumer(LPVOID);//消费者线程
intmain()
{
//创建各个互斥信号
g_hMutex=CreateMutex(NULL,FALSE,NULL);
BUFFER-
g_hFullSemaphore
CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF
1,NULL);
g_hEmptySemaphore
CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);
//总的线程数
constunsignedshortTHREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;
HANDLEhThreads[PRODUCERS_COUNT];//各线程的handle
DWORDproducerID[CONSUMERS_COUNT];//生产者线程的标识符
DWORDconsumerID[THREADS_COUNT];//消费者线程的标识符
//创建生产者线程
for(inti=0;ihThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);
if(hThreads[i]==NULL)return-1;
}
//创建消费者线程
for(i=0;ihThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Cons
umer,NULL,0,&consumerID[i]);
if(hThreads[i]==NULL)return-1;
}
while(g_continue){
if(getchar()){//按回车后终止程序运行
g_continue=false;
}
}
return0;
}
voidProduce()
{
std:
:
cerr<<"Producing"<<++ProductID<<"...";
std:
:
cerr<<"Succeed"<:
endl;
}
//把新生产的产品放入缓冲区
voidAppend()
std:
:
cerr<<"Appendingaproduct...";g_buffer[in]=ProductID;
in=(in+1)%SIZE_OF_BUFFER;std:
:
cerr<<"Succeed"<:
endl;
//输出缓冲区当前的状态
for(inti=0;i:
cout<
"<:
cout<<"<--生产";
if(i==out)std:
:
cout<<"<--消费";std:
:
cout<:
endl;
}
}
//从缓冲区中取出一个产品
voidTake()
{
std:
:
cerr<<"Takingaproduct...";ConsumeID=g_buffer[out];
out=(out+1)%SIZE_OF_BUFFER;std:
:
cerr<<"Succeed"<:
endl;
//输出缓冲区当前的状态
for(inti=0;i:
cout<
"<:
cout<<"<--生产";if(i==out)std:
:
cout<<"<--消费";std:
:
cout<:
endl;
}
}
//消耗一个产品
voidConsume()
{
std:
:
cerr<<"Consuming"<:
cerr<<"Succeed"<:
endl;
}
//生产者
DWORDWINAPIProducer(LPVOIDlpPara)
{
while(g_continue){
WaitForSingleObject(g_hFullSemaphore,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
Produce();
Append();
Sleep(1500);
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptySemaphore,1,NULL);
}
return0;
}
//消费者
DWORDWINAPIConsumer(LPVOIDlpPara)
{
while(g_continue){
WaitForSingleObject(g_hEmptySemaphore,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
Take();
Consume();
Sleep(1500);
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullSemaphore,1,NULL);
}return0;
}