同步机构Word格式文档下载.docx

上传人:b****6 文档编号:21794930 上传时间:2023-02-01 格式:DOCX 页数:22 大小:340.56KB
下载 相关 举报
同步机构Word格式文档下载.docx_第1页
第1页 / 共22页
同步机构Word格式文档下载.docx_第2页
第2页 / 共22页
同步机构Word格式文档下载.docx_第3页
第3页 / 共22页
同步机构Word格式文档下载.docx_第4页
第4页 / 共22页
同步机构Word格式文档下载.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

同步机构Word格式文档下载.docx

《同步机构Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《同步机构Word格式文档下载.docx(22页珍藏版)》请在冰豆网上搜索。

同步机构Word格式文档下载.docx

品。

那么,用PV操作来实现生产者和消费者之间的同步,生产者和消费者两个进程的程序

如下:

B:

array[0..9]ofproducts;

s1,s2:

semaphore;

IN,out;

integer;

IN:

=0;

out:

cobegin

procedureproducer;

c:

products;

begin

L1:

produce(c);

p(s1);

B[IN]:

=C;

=(IN+1)mod10;

v(s2);

gotoL1

end;

procedureconsumer;

x:

L2:

P(s2);

=B[out];

=(out+1)mod10;

v(s1);

consume(x);

gotoL2

coend

其中的semaphore和products是预先定义的两个类型,在模拟实现中semaphore用integer

或char等代替。

(3)进程控制块PCB。

为了纪录进程执行时的情况,以及进程让出处理器后的状态,断点等信息,每个进程

都有一个进程控制块PCB。

在模拟实验中,假设进程控制块的结构如图4-1。

其中进程的状

态有:

运行态、就绪态、等待态和完成态。

当进程处于等待态时,在进程控制块PCB中要说

明进程等待原因(在模拟实验中进程等待原因为等待信号量s1或s2);

当进程处于等待态或

就绪态时,PCB中保留了断点信息,一旦进程再度占有处理器则就从断点位置继续运行;

进程处于完成状态,表示进程执行结束。

(4)处理器的模拟。

计算机硬件提供了一组机器指令,处理器的主要职责是解释执行机器指令。

为了模拟

生产者和消费者进程的并发执行,我们必须模拟一组指令和处理器职能。

模拟的一组指令见图4-2,其中每条指令的功能由一个过程来实现。

用变量PC来模拟

“指令计数器”,假设模拟的指令长度为1,每执行一条模拟指令后,PC加1,指出下一条

指令地址。

使用模拟的指令,可把生产者和消费者进程的程序表示为图4-3的形式。

定义两个一维数组PA[0..4]和SA[0..4],每一个PA[i]存放生产者程序中的一条模拟

指令执行的入口地址;

每个SA[i]存放消费者程序中的一条模拟指令执行的入口地址。

于是

模拟处理器执行一条指令的过程为:

取出PC之值,按PA[PC]或SA[PC]得模拟指令执行的

入口地址,将PC之值加1,转向由入口地址确定的相应的过程执行。

(5)程序设计

本实验中的程序由三部分组成:

初始化程序、处理器调度程序、模拟处理器指令执行程

序。

各部分程序的功能及相互间的关系由图4-4至图4-7指出。

初始化程序:

模拟实验的程序从初始化程序入口启动,初始化工作包括对信号量S1、

S2赋初值,对生产者、消费者进程的PCB初始化。

初始化后转向处理器调度程序,其流程

如图4-4

处理器调度程序:

在计算机系统中,进程并发执行时,任一进程占用处理器执行完一条

指令后就有可能被打断而让出处理器由其他进程运行。

故在模拟系统中也类似处理,每当执

行一条模拟的指令后,保护当前进程的现场,让它成为非运行状态,由处理器调度程序按随

机数再选择一个就绪进程占用处理器运行。

处理器调度程序流程见图4-5。

模拟处理器指令执行程序:

按“指令计数器”PC之值执行指定的质量,且PC加1指向

下一条指令。

模拟处理器指令执行的程序流程见图4-6和4-7。

另外,为了使得模拟程序有一个结束条件,在图4-6中附加了“生产者运行结束”的条

件判断,模拟时可以采取人工选择的方法实现。

图4-7给出了P(S)和V(S)模拟指令执

行过程的流程。

其他模拟指令的执行过程已在图4-2中指出。

四源程序

#include<

string.h>

#include<

ctype.h>

malloc.h>

/*malloc()等*/

limits.h>

/*INT_MAX等*/

stdio.h>

/*EOF(=^Z或F6),NULL*/

stdlib.h>

/*atoi()*/

io.h>

/*eof()*/

math.h>

/*floor(),ceil(),abs()*/

process.h>

/*exit()*/

#include<

iostream>

usingnamespacestd;

time.h>

#defineBUF10//缓存的大小

#defineMAX20//最大可以输入的字符

//数据结构的定义和全局变量

typedefstructPcb{

charname[10];

//进程名

charstate[10];

//运行状态

charreason[10];

//若阻塞,其原因

intbreakp;

//断点保护

structPcb*next;

//阻塞时的顺序

}Pcb,*link;

ints1,s2;

//信号量

linkp1;

//生产者进程

linkc1;

//消费者进程

charstr[MAX];

//输入的字符串

charbuffer[BUF];

//缓冲池

intlen;

//输入长度

intsp=0;

//string的指针

intin=0;

//生产者指针

intout=0;

//消费者指针

chartemp;

//供打印的临时产品

charrec_p[MAX];

//生产记录

intrp1=0;

//生产记录指针

charrec_c[MAX];

//消费记录

intrp2=0;

//消费记录指针

linkready;

//就绪队列

linkb_s1;

//s1阻塞队列

linkb_s2;

//s2阻塞队列

intpc;

//程序计数器

intcount;

//字符计数器

intcon_cnt;

//消费计数器

voidinit();

//初始化

voidp(ints);

//P操作

voidv(ints);

//V操作

voidblock(ints);

//阻塞函数

voidwakeup(ints);

//唤醒函数

voidcontrol();

//处理机调度

voidprocessor();

//处理机执行

voidprint();

//打印函数

voidinit(){//初始化

s1=BUF;

s2=0;

p1=(link)malloc(sizeof(Pcb));

//建立新的结点,并初始化为生产者

strcpy(p1->

name,"

Producer"

);

state,"

Ready"

reason,"

Null"

p1->

breakp=0;

next=NULL;

c1=(link)malloc(sizeof(Pcb));

//建立新的结点,并初始化为消费者

strcpy(c1->

Consumer"

c1->

ready=p1;

ready->

next=c1;

//初始化为生产进程在前,消费进程在后

b_s1=NULL;

b_s2=NULL;

//阻塞进程为NULL

pc=0;

con_cnt=0;

}

voidp(ints){

if(s==1){//p(s1)

s1--;

if(s1<

0)

block

(1);

//阻塞当前生产进程

else{

printf("

\t*s1信号申请成功!

\n"

ready->

breakp=pc;

//保存断点

}

}

else{//p(s2)

s2--;

if(s2<

block

(2);

//阻塞当前消费进程

\t*s2信号申请成功!

voidv(ints){

if(s==1){//v(s1)

s1++;

=0)

wakeup

(1);

//唤醒生产进程

ready->

else{//v(s2)

s2++;

=0)

wakeup

(2);

//唤醒消费进程

voidblock(ints){//阻塞函数的定义

linkp;

intnum1=0;

intnum2=0;

if(s==1){//生产进程

strcpy(p1->

Block"

//改变状态

S1"

//说明原因

p=b_s1;

while(p){

num1++;

p=p->

next;

//p的值为NULL,表示队尾

if(!

b_s1)

b_s1=p1;

else

p=p1;

p1->

printf("

\t*p1生产进程阻塞了!

ready=ready->

//在就绪队列中去掉,指向下一个

num1++;

else{//消费进程

strcpy(c1->

S2"

p=b_s2;

num2++;

}

b_s2)

b_s2=c1;

p=c1;

//在就绪队列中去掉,指向下一个

c1->

\t*c1消费进程阻塞了!

num2++;

}

printf("

\t*阻塞的生产进程个数为:

%d\n"

num1);

\t*阻塞的消费进程个数为:

num2);

voidwakeup(ints){//唤醒函数的定义

linkq=ready;

if(s==1){//唤醒b_s1队首进程,生产进程队列

b_s1=b_s1->

//阻塞指针指向下一个阻塞进程

strcpy(p->

while(q)//插入就绪队列

q=q->

q=p;

p->

\t*p1生产进程唤醒了!

else{//唤醒b_s2队首进程,消费进程队列

b_s2=b_s2->

while(q->

next)//插入就绪队列

q->

next=p;

\t*c1消费进程唤醒了!

voidcontrol()//处理器调度程序

{

intrd;

intnum=0;

linkp=ready;

if(ready==NULL)//若无就绪进程,结束

return;

while(p)//统计就绪进程个数

{

num++;

p=p->

//最终p变为NULL

\t*就绪进程个数为:

num);

time_tt;

srand((unsigned)time(&

t));

rd=rand()%num;

//随机函数产生随机数

if(rd==1){

p=ready;

strcpy(ready->

Run"

next->

else

pc=ready->

breakp;

voidprocessor(){//模拟处理器指令执行

if(strcmp(ready->

)==0)//当前进程为生产者

switch(pc)

{

case0:

//produce

\t*生产者生产了字符%c\n"

str[sp]);

rec_p[rp1]=str[sp];

//添加到生产记录

sp=(sp+1)%len;

pc++;

break;

case1:

//p(s1)

p

(1);

case2:

//put

buffer[in]=rec_p[rp1];

//放到缓冲区

\t*%c字符成功入驻空缓存!

buffer[in]);

rp1++;

in=(in+1)%BUF;

case3:

//v(s2)

\t*释放一个s2信号\n"

v

(2);

case4:

//goto01

\t*生产进程goto0操作\n"

pc=0;

count--;

//剩余字符个数减1

\t*剩余字符count=%d个\n"

count);

if(count<

=0){//生产结束

printf("

\t*生产者结束生产!

strcpy(p1->

Stop"

ready->

breakp=-1;

ready=ready->

//在就绪队列中去掉

}

else//当前进程为消费者

case0:

//p(s2)

p

(2);

//get

\t*消费者取字符!

temp=buffer[out];

out=(out+1)%BUF;

//v(s1)

\t*释放一个s1\n"

v

(1);

//consume

\t*消费了字符%c\n"

temp);

rec_c[rp2]=temp;

//添加到消费记录

rp2++;

con_cnt++;

if(con_cnt>

=len){

strcpy(c1->

//完成态

c1->

return;

//goto0

\t*消费进程goto0操作\n"

voidprint(){

inti,j;

————————生产者消费者模拟———————\n"

*模拟过程的字符串为:

\t"

%s\n"

&

str);

*已生产:

"

for(j=0;

j<

=rp1;

j++)

%c"

rec_p[j]);

\n*空缓存:

for(j=rp2;

buffer[j]);

\n*已消费:

=rp2;

rec_c[j]);

\n———————进程控制块的信息————————\n"

进程名\t\t状态\t等待原因\t断点\n"

%s\t%s\t%s\t\t%d\n\n"

p1->

name,p1->

state,p1->

reason,p1->

breakp);

%s\t%s\t%s\t\t%d\n"

c1->

name,c1->

state,c1->

reason,c1->

———————————————————————\n"

1.继续0.退出\n"

scanf("

%d"

i);

if(i==0){

exit(0);

voidmain(){

*生产者消费者模拟\n"

—————————\n"

*请输入字符串:

%s"

str);

//string数组存放将要产生的字符

len=strlen(str);

count=len;

//输入字符的个数

init();

while(con_cnt<

len)//消费完所有的字符为结束

{

system("

cls"

//清屏操作

—————————模拟指令流程————————\n"

control();

//处理器调度程序

processor();

//模拟处理器指令执行

print();

//输出显示各个信息

\n程序结束!

五运行结果

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 法学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1