C语言编程模拟生产者和消费者问题Word文档格式.docx

上传人:b****2 文档编号:3692160 上传时间:2023-05-02 格式:DOCX 页数:17 大小:19.09KB
下载 相关 举报
C语言编程模拟生产者和消费者问题Word文档格式.docx_第1页
第1页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第2页
第2页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第3页
第3页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第4页
第4页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第5页
第5页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第6页
第6页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第7页
第7页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第8页
第8页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第9页
第9页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第10页
第10页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第11页
第11页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第12页
第12页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第13页
第13页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第14页
第14页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第15页
第15页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第16页
第16页 / 共17页
C语言编程模拟生产者和消费者问题Word文档格式.docx_第17页
第17页 / 共17页
亲,该文档总共17页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

C语言编程模拟生产者和消费者问题Word文档格式.docx

《C语言编程模拟生产者和消费者问题Word文档格式.docx》由会员分享,可在线阅读,更多相关《C语言编程模拟生产者和消费者问题Word文档格式.docx(17页珍藏版)》请在冰点文库上搜索。

C语言编程模拟生产者和消费者问题Word文档格式.docx

其中W(s)表示将调用过程的进程置为等待信号量s的状态;

R(s)表示

释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习

中可把上述的semaphore直接改成integer。

(2)生产者——消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

消费者每次从缓冲器内取出一件产品去消费。

禁止生产者将产品放入已满的缓冲器内,禁止消费者从空缓冲器内以产品。

假定缓冲器内可同时存放10件产品。

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

B:

array[0..9]ofproducts;

s1,s2;

semaphore;

s1:

=10,s2:

=0;

IN,out:

integer;

IN:

out:

cobegin

procedureproducer;

c:

products;

begin

L1:

Produce(c);

P(s1);

B[IN]:

=C;

=(IN+1)mod10;

V(s2);

gotoL1end;

procedureconsumer;

x:

products;

begin

L2:

p(s2);

x:

=B[out];

out:

=(out+1)mod10;

v(s1);

consume(x);

gotoL2

end;

coend.

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

semaphore用integer代替,products可用integer或char等代替。

(3)进程控制块PCB。

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

每个进程都有一个进程控制块PCB。

在模拟实习中,假设进程控制块的结构如

图3-1。

其中进程的状态有:

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

当进程处于等待态时,在进程控制块PCB中要说明进程等待原因(在模拟实习中进程等待原因是为等待信号量s1或s2);

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

当进程处于完成状

态,表示进程执行结束。

进程名

状态

等待原因

断点

图3-1进程控制块结构

(4)处理器的模拟。

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

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

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

用变量

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

PC加1,提出下一条指令地址。

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

定义两个一维数组PA[0..4]和SA[0..4],每一个PA[i]存放生产者程序中的一条模拟指令执行的入口地址;

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

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

取出PC之值,按PA[PC]

或SA[PC]得模拟指令执行的入口地址,将PC之值加1,转向由入口地址确定的相应的过程执行。

模拟的指令功能

p(s)

执行P操作原语

v(s)

执行V操作原语

put

B[IN]:

=product;

=(IN+1)mod10

GET

=(out+1)mod10

produce

输入一个字符放入

C中

consume

打印或显示x中的字符

GOTOL

PC:

=L

NOP空操作

图3-2模拟的处理器指令

序号

生产者程序

消费者程序

p(s)

2

1

PUT

v(s1)

3

v(s2)

4

goto0

图3-3生产者和消费者程序

(5)程序设计

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

初始化程序、处理器调度程序、模拟处理器

指令执行程序。

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

图3-4初始化流程

图3-5模拟处理器调度

·

初始化程序:

模拟实习的程序从初始化程序入口启动,初始化工作包括对信号量s1、s2赋初值,对生产者、消费者进程的PCB初始化。

初始化后转向处理调度程序,其流程如图3-4。

处理器调度程序:

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

器执行完一条指令后就有可能被打断而让出处理器由其它进程运行。

故在模拟系统中也类似处理,每当执行一条模拟的指令后,保护当前进程的现场,让它成为非运行态,由处理器调度程序按随机数再选择一个就绪进程占用处理器运行。

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

图3-6模拟处理器指令执行

(a)模拟

P(s)

(b)模拟

V(s)

图3-7

模拟

PV操作的执行

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

按“指令计数器”PC之值执行指定的指令,

且PC加1指向下一条指令。

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

另外,为了使得模拟程序有一个结束条件,在图3-6中附加了“生产者运行结束”的条件判断,模拟时可以采用人工选择的方法实现。

图3-7给出了P(s)和V(s)模拟指令执行过程的流程。

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

附录:

代码

#include<

>

#defineNULL0

structspcb

{

charname;

charstate;

charwhy;

intdd;

};

typedefstructspcbpcb;

pcbproducter,consumer,*process,*process1;

ints1,s2,i,j,in,out,pc,m;

chararray[10];

charc,x;

intpa[6],sa[6];

intp(ints)/*p操作原语*/

s=s-1;

if(s<

0)

process->

state='

B'

;

/*B表示阻塞*/

why='

s'

}

else

W'

/*W表示就绪*/

return(s);

intv(ints)/*v操作原语*/

s=s+1;

=0)

process1->

charRanChar()

chararr[10]={'

a'

'

b'

c'

d'

e'

f'

g'

h'

i'

j'

returnarr[abs(rand()%10)];

voidput()

//printf("

\npleaseproductanychar!

"

);

//scanf("

\n%c"

&

c);

Sleep(1000);

array[in]=RanChar();

in=(in+1)%10;

printf("

productacharis%c!

\n"

array[in-1]);

intk=0;

for(m=0;

m<

10;

m++)

if(array[m]!

='

'

){printf("

%c"

array[m]);

k=k+1;

缓冲池中有%d个产品\n"

k);

voidget()

x=array[out];

\n%cgetacharfronbuffer"

x);

\n"

array[out]='

out=(out+1)%10;

intk=0;

){

k=k+1;

voidgotol()

pc=0;

voidnop()

{;

voiddisp()/*

建立进程显示函数

用于显示当前进程

*/

\nname\tstate\twhy\tddprintf("

|%c\t"

process->

name);

printf("

state);

why);

|%d\t"

dd);

voidinit()/*

初始化程序

s1=10;

/*s1表示空缓冲区的数量

s2=0;

/*s2表示满缓冲区的数量

p'

/*对生产者进程初始化*/

=0;

/*对消费者进程初始化*/

for(intk=0;

k<

k++)

array[k]='

voidbornpa()/*

将生产者程序装入

pa[]中*/

for(i=0;

i<

=3;

i++)

pa[i]=i;

voidbornsa()/*

将消费者程序装入

sa[]中*/

sa[i]=i;

voiddiaodu()/*

处理器调度程序

while(=='

)||=='

))

x=rand();

/*x随机获得一个数*/

x=x%2;

/*对X取于*/

if(x==0)/*若X等于零,则执行生产者进程,反之执行消费者进程*/

process=&

producter;

/*process表示现行进程,将现行进程置为生产者进程*/process1=&

consumer;

process1=&

pc=process->

dd;

i=pc;

/*此时把PC的值付给I*/

if((process->

name=='

)&

&

(process->

state=='

j=pa[i];

pc=i+1;

switch(j)

case0:

s1=p(s1);

dd=pc;

break;

case1:

put();

case2:

s2=v(s2);

case3:

gotol();

elseif((process->

))/*执行消费者进程且该进程处

于就绪状态*/

j=sa[i];

s2=p(s2);

/*申请资源,若没有申请到则跳转*/

get();

s1=v(s1);

}/*endelse*/

}/*endwhile*/

\nTheprogramisover!

voidmain()

init();

bornpa();

bornsa();

diaodu();

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

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2