武汉理工操作系统课程设计——实现生产者-消费者问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课 程 设 计
2014——2015学年 第2学期
课 程 操作系统
学 院 计算机科学与技术学院 专 业 软件卓越工程师

级 软工zy1302
姓 名
指导教师
刘 军
《操作系统原理》课程设计任务书
学生姓名:专业班级:软件zy1302
指导教师:刘军工作单位:计算机科学与技术学院
课程题目:实现生产者消费者(Bounded – Buffer Problem)问题
课程名称:操作系统/Operating System
周数/学分:1周/1学分
先修课程:高级语言程序设计、汇编语言、数据结构、计算机组成原理
适用专业:计算机科学与技术、软件工程
开课学院、系或教研室:计算机科学与技术学院
一、课程设计的目的
通过研究Linux的线程机制和信号量实现生产者消费者(Bounded Buffer)问题的并发控制。

二、课程设计的内容和要求
实现生产者消费者(Bounded – Buffer Problem)问题
通过研究Linux的线程机制和信号量实现生产者消费者(Bounded Buffer)问题的并发控制。

实验条件要求:每人一台与Linux主机联网的Windows主机,普通用户权限。

指导教师签名:2015年6月
系主任(或责任教师)签名:2015年6月
目录
摘要及关键字 (1)
设计题目与要求 (2)
1.总的设计思想及系统平台,语言,工具 (2)
1.1设计思想 (2)
1.2系统平台、语言和工具 (3)
2.数据结构与模块说明 (3)
2.1数据结构 (3)
2.1.1生产者进程结构 (3)
2.1.2消费者进程结构 (3)
2.1.3 POSIX无名信号量 (4)
2.2模块说明 (4)
2.2.1生产者进程 (4)
2.2.2消费者进程 (5)
3.源程序 (6)
4.调试记录 (9)
5.自我评价与总结 (10)
6.参考文献 (10)
评分表 (11)
摘要
现代操作系统引入并发程序设计技术之后,程序的执行不再是顺序的,封闭的。

在多个进程并发运行的过程中,进程之间可能产生相互制约的关系,即竞争和协作。

为了协调各进程有序正确的进行,就需要各进程间能相互通信。

如果各进程之间不加控制,就会产生错误。

这就需要考虑进程之间的同步和互斥等问题。

操作系统中经典的“生产者-消费者”问题正反映了进程并发执行的这种关系。

本课程设计所完成的就是对“生产者-消费者”问题的实现,根据操作系统并发进程、临界区、同步和互斥等基本概念及理论进行设计,在Linux操作系统下,利用Linux操作系统的线程机制和信号量来实现该问题的并发控制。

关键字:生产者-消费者Linux 信号量进程同步进程互斥
实现生产者消费者(Bounded – Buffer Problem)问题
要求:
通过研究Linux的线程机制和信号量实现生产者消费者(Bounded Buffer)问题的并发控制。

实验条件要求:
每人一台与Linux主机联网的Windows主机,普通用户权限。

1.总的设计思想及系统平台,语言,工具
在Linux系统下处理多进程或多线程的并发编程时,进程/线程同步是经常要遇到的问题。

而在众多同步问题的场景中,生产者-消费者问题( Producer-Consumer Problem )是一个几乎每部涉及到同步问题的经典教材都会提到的经典模型。

1.1设计思想:
典型的生产者-消费者问题如下图所示。

生产者和消费者线程共享一个由n个槽的有限缓冲区,生产者线程反复生成新的item并将其插入缓冲区尾部,消费者线程不断从缓冲区头部取出这些item并消费他们。

由于插入和取出item都涉及更新共享变量,所以必须保证对缓冲区的访问是互斥的。

但仅保证互斥访问是不够的,我们还需调度对缓冲区的访问:若缓冲区是满的(无空的slot),则生产者必须等待直到有一个slot变为可用;类似地,若缓冲区是空的(无可用item),则消费者必须等待直到有一个item变为可用。

1.2系统平台,语言和工具:
本课程设计在Linux操作系统下,使用c语言完成,用到的工具有GCC 编译器、vi编译器和Gedit编辑器。

2.数据结构与模块说明
该问题涉及一个大小限定的有界缓冲区(bounded buffer)和两类线程或进程(生产者和消费者)。

在缓冲区中有可用空间时,一个或一组生产者(线程或进程)将创建的产品(数据条目)放入缓冲区,然后由一个或一组消费者(线程或进程)提取这些产品。

产品在生产者和消费者之间传递。

2.1数据结构
2.1.1生产者进程结构:
2.1.2消费者进程结构:
2.1.3 POSIX无名信号量
PV操作是原子操作.也就是操作是不可以中断的,在一定的时间内,只能够有一个进程的代码在CPU上面执行.在系统当中,有时候为了顺利的使用和保护共享资源,提出了信号的概念. POSIX标准提出了有名信号量和无名信号量的概念,由于Linux只实现了无名信号量,我们在这里就只是介绍无名信号量了。

信号量的使用主要是用来保护共享资源,使的资源在一个时刻只有一个进程所拥有.为此可以使用一个信号灯.当信号灯的值为某个值的时候,就表明此时资源不可以使用.否则就表>示可以使用. 为了提供效率,Linux系统提供了下面几个函数
POSIX的无名信号量的函数有以下几个:
int sem_init(sem_t *sem,int pshared,unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem);
2.2模块说明
2.2.1生产者进程:
{
int i = 0;
while(i < 20)
{
semop(emptyid, &P, 1);
semop(mutxid, &P, 1);
array[*(set)%MAXSEM] = i + 1;
printf("Producer %d\n", array[(*set)%MAXSEM]);
(*set)++;
semop(mutxid, &V, 1);
semop(fullid, &V, 1);
i++;
}
sleep(5);
printf("Producer is over");
exit(0);
}
2.2.2消费者进程:
if(fork() == 0)
{
while(1)
{
semop(fullid, &P, 1);
semop(mutxid, &P, 1);
if(*get == 20)
break;
*sum += array[(*get)%MAXSEM];
printf("The Comsumer A Get Number %d\n", array[(*get)%MAXSEM]);
(*get)++;
if(*get == 20)
{
printf("The sum is %d\n", *sum);
}
semop(mutxid, &V, 1);
semop(emptyid, &V, 1);
sleep(1);
}
printf("Consumer A is over");
exit(0);
}
else
{
if(fork() == 0)
{
while(1)
{
semop(fullid, &P, 1);
semop(mutxid, &P, 1);
if(*get == 20)
break;
*sum += array[(*get)%MAXSEM];
printf("The Comsumer B Get Number %d\n", array[(*get)%MAXSEM]);
(*get)++;
if(*get == 20)
printf("The sum is %d\n", *sum);
semop(mutxid, &V, 1);
semop(emptyid, &V, 1);
sleep(1);
}
printf("Consumer B is over");
exit(0);
}
}
}
3.源程序
#include <sys/mman.h>
#include <sys/types.h>
#include <linux/sem.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#define MAXSEM 5
int fullid;
int emptyid;
int mutxid;
int main()
{
struct sembuf P,V;
union semun arg;
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);
set = (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);
*sum = 0;
*get = 0;
*set = 0;
fullid = semget(IPC_PRIV A TE, 1, IPC_CREA T | 00666);
emptyid = semget(IPC_PRIV A TE, 1, IPC_CREA T | 00666);
mutxid = semget(IPC_PRIV A TE, 1, IPC_CREAT | 00666);
arg.val = 0;
if(semctl(fullid, 0, SETV AL, arg) == -1)
{
perror("semctl setval error");
}
arg.val = MAXSEM;
if(semctl(emptyid, 0, SETV AL, arg) == -1)
{
perror("semctl setval error");
}
arg.val = 1;
if(semctl(mutxid, 0, SETV AL, arg) == -1)
{
perror("semctl setval error");
}
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)
{
int i = 0;
while(i < 20)
{
semop(emptyid, &P, 1);
semop(mutxid, &P, 1);
array[*(set)%MAXSEM] = i + 1;
printf("Producer %d\n", array[(*set)%MAXSEM]);
(*set)++;
semop(mutxid, &V, 1);
semop(fullid, &V, 1);
i++;
}
sleep(5);
printf("Producer is over");
exit(0);
}
else
{
if(fork() == 0)
{
while(1)
{
semop(fullid, &P, 1);
semop(mutxid, &P, 1);
if(*get == 20)
break;
*sum += array[(*get)%MAXSEM];
printf("The Comsumer A Get Number %d\n", array[(*get)%MAXSEM]);
(*get)++;
if(*get == 20)
{
printf("The sum is %d\n", *sum);
}
semop(mutxid, &V, 1);
semop(emptyid, &V, 1);
sleep(1);
}
printf("Consumer A is over");
exit(0);
}
else
{
if(fork() == 0)
{
while(1)
{
semop(fullid, &P, 1);
semop(mutxid, &P, 1);
if(*get == 20)
break;
*sum += array[(*get)%MAXSEM];
printf("The Comsumer B Get Number %d\n", array[(*get)%MAXSEM]);
(*get)++;
if(*get == 20)
printf("The sum is %d\n", *sum);
semop(mutxid, &V, 1);
semop(emptyid, &V, 1);
sleep(1);
}
printf("Consumer B is over");
exit(0);
}
}
}
sleep(20);
return 0;
}
4.调试记录
4.1编译,链接
4.2执行
……
5.自我评价与总结
我从出生到现在一直习惯使用Windows操作系统,刚接触Linux时,心里有些许的担心,不过随着使用Linux操作系统的时间增多,自己对这个操作系统也越来越熟悉和喜欢,遇到不懂的问题,自己翻翻书,上网搜资料,与同学激烈探讨,这些感觉让我觉得很棒。

另外,觉得该实验题蛮好的,操作系统老师所教授的信号量机制解决进程互斥和同步问题都得到了训练,同时也让我温习以前所学习的高级语言,应该来说该题目很适合这个时候给我打一个强心针。

进程的同步与互斥是操作系统课程中非常重要的一部分内容。

通过本次课程设计,我不仅学会了使用信号量机制解决有限缓冲区的生产者消费者问题,而且对Linux系统下多线程编程有了更深入的了解。

6.参考文献
[1]Abraham Silberschatz, 《Operating System Concepts(Sixth Edition)(操作系统概念)影印第七版》[M], 高等教育出版社,2004.4
[2]张尧学, 《计算机操作系统教程(第三版)》[M]. 清华大学出版社,2001.7
[3] 庞丽萍, 《操作系统原理(第三版)》[M], 华中科技大学出版社, 2000.12
本科生课程设计成绩评定表
班级:软工zy1302姓名:学号:
及格(60-69分)、60分以下为不及格
指导教师签名:
2015 年6月日。

相关文档
最新文档