操作系统实验五
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验报告
实验五: Linux 信号量与P、V操作函数的定义
1.实验目的
(1)掌握Linux信号量的使用方法和P、V操作函数的定义;
(2)掌握使用P、V操作实现进程之间的同步和互斥的方法;
(3)加深对进程同步互斥概念的理解。
2.实验内容
(1)使用信号量及P、V操作实现进程互斥。阅读附件材料中例4-9,将程序编译连接后运行,观察运行结果。
(2)使用信号量及P、V操作实现子进程之间通过共享内存通信的读写同步,如实验图5-1所示。要求如下:
实验图 5-1
①请参考附件材料中的例4-11,设计一个父进程,创建三个子进程。3个子进程中一
个是生产者进程,两个是消费者进程。父子进程都使用父进程创建的共享存储区进
行通信。
②由生产者进程发送数值1~10到由5个缓冲区组成的共享内存中,两个消费者进程
轮流接受并输入这10个数据,同时将两个消费者进程对读出的所有数据进行累加
求和。
③3个子进程结束后,由父进程输出两个消费者进程所读出数据的累加和。
它们的同步关系使用P、V操作系统。
提示:在例4-11使用2个共享内存的基础上再使用一个共享内存来存放读出信息的累加和,由两个消费者进程和父进程共享使用。
3.实验思考
(1)针对每个信号量需要进行哪些定义?
答:①定义信息量的标识符②定义信息量的数据结构③定义信息量的P操作④定义信息量的v操作
(2)总结使用信号量系统调用的步骤与方法。
答:1.定义信号量标识符2.定义信号量数据结构3.申请只有一个信号量的信号量集4.
分别对每个信号量赋初值5.定义信号量P操作6.定义信号量v操作7.对信号量执行p 操作8.对信号量执行v操作9.撤销信号量
(3)进程之间如何使用信号量及其P、V操作实现互斥?
答:父子进程共享一个临界资源,使用信号量来控制每个进程使用临界资源的先后顺序,等第一个进程遇到撤销信号量时,第二个进程才开始执行,这样就达到互斥。
(4)进程之间如何使用信号量及其P、V操作实现同步?
答:信号量有父进程定义、申请、初始化,然后父子进程共享使用,子进程结束后有父进程进行撤销,父进程执行条件为单缓冲区为空,设信号量为emptyid,初值为1;子进程执行条件为单缓冲区不为空,设信号量为fullid,初值为0.
(5)总结数值型共享内存作为变量或作为数组的使用方法。
答:先创建共享存储区,然后附接共享存储区到进程空间,给共享存储区赋初值,创建信号量empty、full、mutex且初始化,然后创建子进程,先写数据到共享存储区,并让缓冲区计数+1,然后父进程根据信号量和P、V操作进行返回且回收子进程,然后断开并撤销共享内存和信号量集。
4.实验代码
5-1:
#include
#include
#include
#include
#include
#include
#ifndef _SEMUN_H
#define _SEMUN_H
union semun
{
int val;
struct semid_ds*buf;
unsigned short int*array;
struct seminfo*_buf;
};
#endif
/*以下为函数申明*/
static int set_mutex(void); /*信号量mutex赋初值函数*/
static void del_mutex(void); /*删除信号量mutex函数*/
static int p_mutex(void); /* P(mutex)操作函数*/
static int v_mutex(void); /* V(mutex)操作函数*/
static int sem_id; /*信号量标识*/
int main()
{
int chld,i,j;
sem_id=semget((key_t)1234,1,0666|IPC_CREAT); /*创建互斥信号量*/
set_mutex(); /*设置初值*/
while((chld=fork())==-1); /*创建子进程*/
if(chld>0) /*父进程返回*/
{
i=1;
while(i<=3) /*循环3次*/
{
sleep(1);
p_mutex(); /*进入临界区前执行P(mutex)*/
printf("prnt in\n");
sleep(1);
printf("prnt out\n");
v_mutex(); /*出临界区执行V(mutex)*/
i++;
}
wait(0); /*等待子进程终止*/
del_mutex(); /*删除信号量*/
exit(0);
}
else /*子进程返回*/
{
j=1;
while(j<=3) /*循环3次*/
{
sleep(1);
p_mutex(); /*进入临界区前执行(mutex)*/
printf("chld in\n");
sleep(1);
printf("chld out\n");
v_mutex(); /*出临界区执行V(mutex)*/