生产者消费者 BoundedBuffer Problem文档格式.docx
- 文档编号:22504499
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:16
- 大小:181.58KB
生产者消费者 BoundedBuffer Problem文档格式.docx
《生产者消费者 BoundedBuffer Problem文档格式.docx》由会员分享,可在线阅读,更多相关《生产者消费者 BoundedBuffer Problem文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
2)总的设计思想及系统平台、语言、工具等。
3)数据结构与模块说明(功能与流程图)
4)运行结果与运行情况
(提示:
(1)有界缓冲区可用数组实现。
(2)编译命令可用:
cc-lpthread-o 目标文件名 源文件名
(3)多线程编程方法参见附件。
)
3.调试报告:
1)调试记录
2)自我评析和总结
上机时间安排:
周一~五下午14:
00-18:
00(6月15日开始)
指导教师签名:
2010年6月15日
系主任(或责任教师)签名:
2010年6月15日
实现生产者消费者(Bounded–BufferProblem)问题
摘要
生产者与消费者问题是《操作系统》中经典进程同步问题的典型代表。
本设计介绍了基于单缓冲区和多缓冲区的生产者与消费者问题在C语言中的多种实现机制。
这种用C实现生产者与消费者问题的思想不仅可以更好的理解这方面的内容,而且还具有很强的实践意义。
1设计题目与要求
1.1设计题目:
1.2设计要求:
通过研究Linux的线程机制和信号量实现生产者消费者(BoundedBuffer)问题的并发控制。
2总的设计思想及系统平台、语言、工具
2.1设计思想:
2.1.1具体的要求
(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容.当前指针位置和生产者/消费者线程的标识符
(2)生产者和消费者各有两个以上
(3)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。
2.1.2POSIX无名信号量
PV操作是原子操作.也就是操作是不可以中断的,在一定的时间内,只能够有一个进程的代码在CPU上面执行.在系统当中,有时候为了顺利的使用和保护共享资源,提出了信号的概念.POSIX标准提出了有名信号量和无名信号量的概念,由于Linux只实现了无名信号量,我们在这里就只是介绍无名信号量了。
信号量的使用主要是用来保护共享资源,使的资源在一个时刻只有一个进程所拥有.为此可以使用一个信号灯.当信号灯的值为某个值的时候,就表明此时资源不可以使用.否则就表>
示可以使用.为了提供效率,Linux系统提供了下面几个函数
POSIX的无名信号量的函数有以下几个:
intsem_init(sem_t*sem,intpshared,unsignedintvalue);
intsem_destroy(sem_t*sem);
intsem_wait(sem_t*sem);
intsem_trywait(sem_t*sem);
intsem_post(sem_t*sem);
intsem_getvalue(sem_t*sem);
sem_init创建一个信号灯,并初始化其值为value.pshared决定了信号量能否在几个进程间共享.由于目前Linux还没有实现进程间共享信号灯,所以这个值只能够取0.sem_destroy是用来删除信号灯的.sem_wait调用将阻塞进程,直到信号灯的值大于0.这个函数返回的时候自动的将信号灯的值的件一.sem_post和sem_wait相反,是将信号灯的内容加一同时发出信号唤醒等待的进程..sem_trywait和sem_wait相同,不过不阻塞的,当信号灯的值为0的时候返回EAGAIN,表示以后重试.sem_getvalue得到信号灯的值.
这几个函数的使用相当简单的.比如我们有一个程序要向一个系统请求一个资源时.首先创建一个信号灯,并使其初始值为1,表示有一个资源可用.然后一个进程调用sem_wait由于这个时候信号灯的值为1,所以这个函数返回,打印机开始打印了,同时信号灯的值为0了.如果第二个进程要使用,调用sem_wait时候,由于信号灯的值为0,资源不可用,于是被阻塞了.当第一个进程对资源的使用完毕以后,调用sem_post信号灯的值为1了,这个时候系统通知第二个进程,于是第二个进程的sem_wait返回.第二个进程开始工作了.
2.1.3SystemV信号量
为了解决上面的问题,也可以使用SystemV信号量.并且Linux实现了SystemV信号量.这样就可以用实例来解释了.SystemV信号量的函数主要有下面几个.
key_tftok(char*pathname,charproj);
intsemget(key_tkey,intnsems,intsemflg);
intsemctl(intsemid,intsemnum,intcmd,unionsemunarg);
intsemop(intsemid,structsembuf*spos,intnspos);
structsembuf{
shortsem_num;
/*使用那一个信号*/
shortsem_op;
/*进行什么操作*/
shortsem_flg;
/*操作的标志*/
};
ftok函数是根据pathname和proj来创建一个关键字.semget创建一个信号量.成功时返回信号的ID,key是一个关键字,可以是用ftok创建的也可以是IPC_PRIVATE表明由系统选用一个关键字.nsems表明我们创建的信号个数.semflg是创建的权限标志,和创建一个文件的标志相同.
semctl对信号量进行一系列的控制.semid是要操作的信号标志,semnum是信号的个数,cmd是操作的命令.经常用的两个值是:
SETVAL(设置信号量的值)和IPC_RMID(删除信号灯).arg是一个给cmd的参数.
semop是对信号进行操作的函数.semid是信号标志,spos是一个操作数组表明要进行什么操作,nspos表明数组的个数.如果sem_op大于0,那么操作将sem_op加入到信号量的值中,并唤醒等待信号增加的进程.如果为0,当信号量的值是0的时候,函数返回,否则阻塞直到信号量的值为0.如果小于0,函数判断信号量的值加上这个负值.如果结果为0唤醒等待信号量为0的进程,如果小与0函数阻塞.如果大于0,那么从信号量里面减去这个值并返回.
2.1.4pthread_xxx()API
主要包含数据结构pthread_t它记录一个线程的号,主要包括下面几个函数,完成不同的功能:
intpthread_create(pthread_t*thread,pthread_attr_t*attr,void*(*start_routine)(void*),void*arg);
创建一个线程。
pthread_join(pthread_t*thread,void**return);
等待一个线程结束。
pthread_exit(void*returnval);
结束一个线程。
2.2.系统平台:
一台Linux主机且有超级用户权限
2.3.编程工具:
VI编辑器,Gedit编辑器
3.模块说明
3.1.生产者进程:
if(fork()==0)
{
inti=0;
while(i<
100)
semop(emptyid,&
P,1);
semop(mutxid,&
P,1);
array[*(set)%MAXSEM]=i+1;
printf("
Producer%d\n"
array[(*set)%MAXSEM]);
(*set)++;
V,1);
semop(fullid,&
i++;
}//endofwhileinline62
sleep(10);
Producerisover"
);
exit(0);
}/……
3.2消费者进程:
//消费者A进程
if(fork()==0)
while
(1)
if(*get==100)
break;
*sum+=array[(*get)%MAXSEM];
TheComsumerAGetNumber%d\n"
array[(*get)%MAXSEM]);
(*get)++;
if(*get==100)
Thesumis%d\n"
*sum);
V,1);
sleep
(1);
}//endofwhile
(1)inline82
ConsumerAisover"
}//endofifinline81
else
{//消费者B进程
TheComsumerBGetNumber%d\n"
}//endofwhile
(1)inline105
ConsumerBisover"
}//endofifinline103
}//endofelseinline101
}……
4.源程序:
#include<
sys/mman.h>
sys/types.h>
linux/sem.h>
fcntl.h>
unistd.h>
stdio.h>
errno.h>
time.h>
#defineMAXSEM5
////声明三个信号灯ID
intfullid;
intemptyid;
intmutxid;
intmain()
{
structsembufP,V;
;
unionsemunarg;
////声明共享内存
int*array;
int*sum;
int*set;
int*get;
//映射共享内存
array=(int*)mmap(NULL,sizeof(int)*5,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
sum=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
get=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
set=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
*sum=0;
*get=0;
*set=0;
//生成信号灯
fullid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
mutxid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
//为信号灯赋值
arg.val=0;
if(semctl(fullid,0,SETVAL,arg)==-1)perror("
semctlsetvalerror"
arg.val=MAXSEM;
if(semctl(emptyid,0,SETVAL,arg)==-1)perror("
arg.val=1;
if(semctl(mutxid,0,SETVAL,arg)==-1)perror("
setctlsetvalerror"
//初始化P,V操作
V.sem_num=0;
V.sem_op=1;
V.sem_flg=SEM_UNDO;
P.sem_num=0;
P.sem_op=-1;
P.sem_flg=SEM_UNDO;
//生产者进程
if(fork()==0)
}//endofifinline59
else
//消费者A进程
}//endofelseinline78
sleep(20);
return0;
}//endofmain
5.运行结果与运行情况
运行截图如下:
6.调试记录:
有三个worning:
7.自我评析和总结:
这次操作系统课程设计,我在设计过程中虽然遇到了困难,但是通过上网查阅资料很好的解决了问题,让我真正理解了Linux内核定时器的本质。
其实这个课程设计是我和同学一起完成的,虽然不是很完美,但是起码能让我们很好的理解了什么是生产者—消费者问题。
让我对互斥问题有了更深的见解。
8.参考文献
[1]《OperatingSystemConcepts(SixthEdition)(操作系统概念)影印版》AbrahamSilberschatz编高等教育出版社2003年
[2]《计算机操作系统教程(第三版)》张尧学编清华大学出版社2001年
[3]《操作系统原理(第三版)》庞丽萍华中科技大学出版社2000年
本科生课程设计成绩评定表
班级:
软件0703 姓名:
学号:
0120710680319
序号
评分项目
满分
实得分
1
学习态度认真、遵守纪律
10
2
设计分析合理性
3
设计方案正确性、可行性、创造性
20
4
设计结果正确性
40
5
设计报告的规范性
6
设计验收
总得分/等级
评语:
注:
最终成绩以五级分制记。
优(90-100分)、良(80-89分)、中(70-79分)、
及格(60-69分)、60分以下为不及格
指导教师签名:
2010年6月15日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 生产者消费者 BoundedBuffer Problem 生产者 消费者