实验二进程同步实验_第1页
实验二进程同步实验_第2页
实验二进程同步实验_第3页
免费预览已结束,剩余8页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验二进程同步一、实验目的:掌握根本的同步算法,理解经典进程同步问题的本质;学习使用Linux的进程同步机制,掌握相关API的使用方法;能利用信号量机制,采用多种同步算法实现不会发生死锁的哲学家进餐程序。、实验平台:虚拟机:VMWare9 以上编辑器:Gedit | Vim编译器:Gcc三、实验内容:1以哲学家进餐模型为依据,在Linux控制台环境下创建5个进程,用semget函数创建一个信号量集5个信号量,初值为1,模拟哲学家的思考和进餐行为:每一位哲学家饥 饿时,先拿起左手筷子,再拿起右手筷子;筷子是临界资源,为每一支筷子定义1个互斥信号量;想拿到筷子需要先对信号量做P操作,使用完释放筷子

2、对信号量做V操作。伪代码描述:semaphore chopstick5=1,1,1,1,1;? 第i位哲学家的活动可描述为:doprintf("%d is thinkingn",i);prin tf("%d is hun gryn",i);wait(chopstick i );/拿左筷子wait(chopstick (i+1) % 5 );/拿右筷子prin tf("%d is eatin gn",i);signal(chopstick i );/放左筷子signal(chopstick (i+1) % 5 );放右筷子whiletr

3、ue;运行该组进程,观察进程是否能一直运行下去,假如停滞如此发生了什么现象?并分析 原因。2解决哲学家进餐问题可采用如下方法:a仅当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐;b.至多只允许有4位哲学家同时去拿左边的筷子,最终能保证至少 有一位哲学家能够进餐;c.规定奇数号哲学家先拿起他左手的筷子,然后再拿起他右手的筷 子,而偶数号哲学家如此先拿起他右手的筷子,然后再拿起他左手的筷子。方法a在示例程序中给出,请用方法 b和c写出不会发生死锁的哲学家进餐程序。3设计程序,实现生产者/消费者进程(线程)的同步与互斥。在该程序中创建4个进程或线程模拟生产者和消费者,实现进程(线程)的同步与

4、互斥。实验结果:使用a方法结果哲学家就餐问题whtcntSEpwhtcntss-vtrtuaVBox:/De£ktop$ gcc a.c -o a whtentsswhtcniss-VtrtualBox:-/Desktops /a 0 Is thinking4 is thinking3 is thinkins2 Is thinking1 is thiriklng3 Is hungryA is hungry1 ts hjngry4 ts eating2 Is hungry fl Is h jngrj/4 Is thtrikingi3 ts eating3 ts thtnktng2 ts

5、 eating4 Is hungry2 is thinkvng1 is eating3 is hungry1 Is tlinking o Is eatlbg2 Is hungry使用b方法解决哲学家就餐问题 源码如下:#i nclude <stdio.h>#i nclude <stdlib.h>#in clude <stri ng.h>#in clude <stdi nt.h>#in clude <stdbool.h>#in clude <errno .h>#in clude <uni std.h>#in cl

6、ude <sys/types.h>#in clude <sys/stat.h>#in clude <sys/ipc.h>#in clude <sys/sem.h>#i nclude <sys/wait.h>union sem unint val;struct semid_ds *buf;un sig ned short *array;struct sem info *_buf;#defi ne ERR_EXIT(m) do perror(m); exit(EXIT_FAILURE); while(0)获取互斥信号量void wait_

7、mutex(int mutex)struct sembuf sb=0,-1,0;semop(mutex,&sb,1);对互斥信号量进展操作 /取得筷子void wait_v(i nt semid,i nt num)struct sembuf sb= nu m,-1,0;semop(semid, &sb,1);/释放筷子void sig nal_p(i nt semid,i nt num)struct sembuf sb= nu m,1,0;semop(semid, &sb,1);/释放互斥变量mutexvoid sig nal_mutex(i nt semid0)str

8、uct sembuf sb=0,1,0;semop(semid0,& sb,1);/ph函数void ph(i nt nu m,i nt semid,i nt semid0)in t left=num;int right=( num+1)%5;for(;)prin tf("%d is thinking'n ”, nu m);sleep(1);prin tf("%d is hun gryn", nu m);sleep(1);/wait操作,控制哲学家最多4人能进餐wait_mutex(semidO);wait_v(semid,left);wait_v

9、(semid,right);prin tf("%d is eati ngn", nu m);sleep(1);/signal 操作signal_p(semid,right); 释放右筷子signal_p(semid,left); 释放左快子sig nal_mutex(semidO); 释放互斥信 号量/主函数int main (i nt argc,char *argv)int semid,semid0;/创建两个信号量集semidO=semget(IPC_PRIVATE,1,IPC_CREAT | 0666);semid=semget(IPC_PRIVATE,5,IPC_C

10、REAT | 0666);/union sem un su;su.val=1;int i;for(i=0;i<5;i+))上执行各种控制操作semctl()系统调用在一个信号量集(或集合中的单个信semctl(semid,i,SETV AL,su);设定semid0信号量的初始值union sem un su0;su0.val=4;semctl(semid0,0,SETV AL,su0);/创建4个子进程int num=0;pid_t pid;for(i=1;i<5;i+)pid=fork();if(pid<0) ERR_EXIT("fork"); if(

11、pid=O) num=i;break;第num个哲学家要做的事ph( nu m,semid,semidO);return 0;执行结果LljIBox :-/Desktops get b. c *o b whtcnisswhtciiss-VirtualEox:-/Desktops Jb 0 Is thinktcg 4 ts thinkLrg M ts thinking2 ts thtnkirq1 ts thtnkLrg 0 Is hungry4 Is hunqry3 ts hungry2 is hungry1 ts hungry 日 is eating2 is亡銚ing0 is thinking

12、4 ts eating2 is thinking1 ts eating 0 Is hungry4 Is thinking3 ts coting2 ts hungry1 ts thinking使用c方法解决哲学家就餐问题#in clude <stdio.h>#in clude <stdlib.h>#in clude <stri ng.h>#in clude <stdi nt.h>#in clude <stdbool.h>#in clude <err no .h>#in clude <uni std.h>#in c

13、lude <sys/types.h> #in clude <sys/stat.h> #in clude <sys/ipc.h> #i nclude <sys/sem.h> #i nclude <sys/wait.h> union sem unint val;struct semid_ds *buf;un sig ned short *array;struct sem info *_buf;;#defi ne ERR_EXIT(m) do perror(m); exit(EXIT_FAILURE); while(O)取得筷子void w

14、ait_v(i nt semid,i nt num)struct sembuf sb= nu m,-1,0;semop (num,& sb,1);释放筷子void sig nal_p(i nt semid,i nt num)struct sembuf sb= nu m,-1,0;semop (num,& sb,1);科学家要做的事void ph(i nt semid,i nt num)for(;)死循环判断哲学家的编号是奇数还是偶数奇数先申请左边的筷子,偶数先申请右边的筷子if(nu m%2!=0)/判断奇数prin tf("%d is thinking'n

15、”, nu m);sleep(1);prin tf("%d is hungry'n ”, nu m);sleep(1);/wait操作wait_v(semid, nu m);wait_v(semid,( nu m+1)%5);prin tf("%d is eati ngn", nu m);sleep(1);/signal 操作sig nal_p(semid,( nu m+1)%5);sig nal_p(semid, nu m);if(nu m%2=0)/判断偶数prin tf("%d is thinking'n ”, nu m);slee

16、p(1);prin tf("%d is hungry'n ”, nu m); sleep(1);/wait操作wait_v(semid,( nu m+1)%5);wait_v(semid, nu m);/signal 操作sig nal_p(semid, nu m);sig nal_p(semid,( nu m+1)%5);int main (i nt argc,char *argv)int semid;创建5个信号量semid=semget(IPC_PRIVATE,5,IPC_CREAT | 0666); union sem un su;su.val=1;int i;for

17、(i=0;i<5;i+)注意第二个参数也是索引semctl(semid,i,SETV AL,su);创建4个子进程pid_t pid;int num=5;for(i=0;i<4;i+)pid=fork();if(pid<0) ERR_EXIT("fork");if(pid=0) num=i;break;哲学家要做的事ph(semid, nu m);return 0;whtcnissHhttni士sVirtudlEox:-/Desktops gcc c.c o c whtcntssiwhtcntss-VlrtiMlBox;-/Desktops Jc5 ts

18、thinking3 is thinking2 Is thinking1 Vs th linkingD L5 thinkingSIs hungry3 Is hungryb Is hungry1 Is hungryd ts hungrys is eating2 is thtnkinq3 eating1. Is eating5 Is thinking2 Is hungry3 is thinking1 ts thinking5 Is hungry2 Is thinking勺 i、hunm、生产者和消费者的同步与互斥源代码如下:#in elude <stdio.h>#in elude <

19、;stdlib.h>#in elude <uni std.h>#in elude <pthread.h>#in elude <semaphore.h>#define N 2消费者或者生产者的数目#define M 10 /缓冲数目int in = 0;/生产者放置产品的位置int out = 0; /消费者取产品的位置0,开始时没有产品当满了时阻止生产者放产品 当没产品时阻止消费者消费 号量, 一次只有一个线程访问缓冲int buffM = 0; /缓冲初始化为sem_t empty_sem; /同步信- 号量, sem_t full_sem; / 同

20、步信 号量, pthread_mutex_t mutex; /互斥信' int produet_id = 0;生产者 idint proehase_id = 0; / 消费者 id /*打印缓冲情况*/void prin t()int i;for(i = 0; i < M; i+)printf("%d ", buffi);prin tf("n");/*生产者方法*/void *product()int id = +product_id;while(1)/用sleep的数量可以调节生产和消费的速度,便于观察sleep(1);sleep(1);

21、sem_wait (& empty_sem);pthread_mutex_lock(&m utex);in = in % M;prin tf("product%d in %d. like: t", id, i n);buffi n = 1;prin t();+i n;pthread_mutex_ uni ock (&m utex); sem_post( &full_sem);/*消费者方法*/void *prochase()int id = +prochase_id;while(1)II用sleep的数量可以调节生产和消费的速度,便于观察 s

22、leep(1);IIsleep(1);sem_wait (& full_sem); pthread_mutex_lock(&m utex);out = out % M;prin tf("prochase%d in %d. like: t", id, out);buffout = 0;prin t();+out;pthread_mutex_ uni ock (&m utex); sem_post (& empty_sem);int mai n()pthread_t id1N;pthread_t id2N;int i;int retN;/初始化同

23、步信号量int ini1 = semn it (&empty_sem, 0, M);in t i ni2 = sem丄in it (& full_sem, 0, 0);if(i ni1 && ini2 != 0)prin tf("sem in it failed n ”); exit(1);/初始化互斥信号量int ini3 = pthread_mutex_ in it (&m utex, NULL);if(i ni3 != 0)prin tf("mutex in it failed n ”); exit(1);/创建N个生产者线程f

24、or(i = 0; i < N; i+)reti = pthread_create(&id1i, NULL, product, (void *)(&i); if(reti != 0)prin tf("product%d creati on failed n", i); exit(1);创建N个消费者线程for(i = 0; i < N; i+)reti = pthread_create(&i d2i, NULL, prochase, NULL);if(reti != 0)printf("prochase%d creation f

25、ailed n", i);exit(1);/销毁线程for(i = 0; i < N; i+)pthread _joi n( id1i,NULL);pthread _joi n( id2i,NULL); exit(O);执行结果:whtcnis5fnhtcniss-VtrtjalBox/DesktopJ qcc cs,c - cs -Ipthreed whtcnlsswh tent ss-vtrtjalBOK:-/Desktops、f csprcductl in 0.like;1oa9g080prochasel tn e.like:e0e09&目00product2 in 1*like:e1o000GG0prochasez tn 1* kike:e0eQe9&

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论