实验二进程同步实验_第1页
实验二进程同步实验_第2页
实验二进程同步实验_第3页
实验二进程同步实验_第4页
实验二进程同步实验_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

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

2、到筷子需要先对信号量做P操作,使用完释放筷子对信号量做V操作。伪代码描述:semaphore chopstick5=1,1,1,1,1;第i位哲学家的活动可描述为: doprintf(%d is thinkingn,i);printf(%d is hungryn,i); wait(chopsticki); /拿左筷子 wait(chopstick(i+1) % 5); /拿右筷子 printf(%d is eatingn,i); signal(chopsticki); /放左筷子 signal(chopstick(i+1) % 5); /放右筷子 whiletrue; 运行该组进程,观察进程是

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

4、餐问题使用b方法解决哲学家就餐问题源码如下:#include #include #include #include #include #include #include #include #include #include #include #include union semunint val;struct semid_ds *buf;unsigned short *array;struct seminfo *_buf;#define ERR_E*IT(m) do perror(m); e*it(E*IT_FAILURE); while(0)/获取互斥信号量void wait_mute*(i

5、nt mute*)struct sembuf sb=0,-1,0;semop(mute*,&sb,1);/对互斥信号量进展操作/取得筷子void wait_v(int semid,int num)struct sembuf sb=num,-1,0;semop(semid,&sb,1);/释放筷子void signal_p(int semid,int num)struct sembuf sb=num,1,0;semop(semid,&sb,1);/释放互斥变量mute*void signal_mute*(int semid0)struct sembuf sb=0,1,0;semop(semid0

6、,&sb,1);/ph函数void ph(int num,int semid,int semid0)int left=num;int right=(num+1)%5;for(;)printf(%d is thinkingn,num);sleep(1);printf(%d is hungryn,num);sleep(1);/wait操作,控制哲学家最多4人能进餐wait_mute*(semid0);wait_v(semid,left);wait_v(semid,right);printf(%d is eatingn,num);sleep(1);/signal操作signal_p(semid,ri

7、ght);/释放右筷子signal_p(semid,left);/释放左快子signal_mute*(semid0);/释放互斥信号量/主函数int main(int argc,char *argv)int semid,semid0;/创立两个信号量集semid0=semget(IPC_PRIVATE,1,IPC_CREAT | 0666);semid=semget(IPC_PRIVATE,5,IPC_CREAT | 0666);/union semun su;su.val=1;int i;for(i=0;i5;i+)/semctl()系统调用在一个信号量集(或集合中的单个信号量)上执行各种控

8、制操作semctl(semid,i,SETVAL,su);/设定semid0信号量的初始值union semun su0;su0.val=4;semctl(semid0,0,SETVAL,su0);/创立4个子进程int num=0;pid_t pid;for(i=1;i5;i+)pid=fork();if(pid0) ERR_E*IT(fork);if(pid=0) num=i;break;/第num个哲学家要做的事ph(num,semid,semid0);return 0;执行结果使用c方法解决哲学家就餐问题#include #include #include #include #incl

9、ude #include #include #include #include #include #include #include union semunint val;struct semid_ds *buf;unsigned short *array;struct seminfo *_buf;#define ERR_E*IT(m) do perror(m); e*it(E*IT_FAILURE); while(0)/取得筷子void wait_v(int semid,int num)struct sembuf sb=num,-1,0;semop(num,&sb,1);/释放筷子void

10、signal_p(int semid,int num)struct sembuf sb=num,-1,0;semop(num,&sb,1);/科学家要做的事void ph(int semid,int num)for(;)/死循环/判断哲学家的编号是奇数还是偶数/奇数先申请左边的筷子,偶数先申请右边的筷子if(num%2!=0)/判断奇数printf(%d is thinkingn,num);sleep(1);printf(%d is hungryn,num);sleep(1);/wait操作wait_v(semid,num);wait_v(semid,(num+1)%5);printf(%d

11、is eatingn,num);sleep(1);/signal操作signal_p(semid,(num+1)%5);signal_p(semid,num);if(num%2=0)/判断偶数printf(%d is thinkingn,num);sleep(1);printf(%d is hungryn,num);sleep(1);/wait操作wait_v(semid,(num+1)%5);wait_v(semid,num);/signal操作signal_p(semid,num);signal_p(semid,(num+1)%5);int main(int argc,char *argv

12、)int semid;/创立5个信号量semid=semget(IPC_PRIVATE,5,IPC_CREAT | 0666);union semun su;su.val=1;int i;for(i=0;i5;i+)/注意第二个参数也是索引semctl(semid,i,SETVAL,su);/创立4个子进程pid_t pid;int num=5;for(i=0;i4;i+)pid=fork();if(pid0) ERR_E*IT(fork);if(pid=0) num=i;break;/哲学家要做的事ph(semid,num);return 0;生产者和消费者的同步与互斥源代码如下:#incl

13、ude #include #include #include #include #define N 2 / 消费者或者生产者的数目#define M 10 / 缓冲数目int in = 0; / 生产者放置产品的位置int out = 0; / 消费者取产品的位置int buffM = 0; / 缓冲初始化为0, 开场时没有产品sem_t empty_sem; / 同步信号量, 当满了时阻止生产者放产品sem_t full_sem; / 同步信号量, 当没产品时阻止消费者消费pthread_mute*_t mute*; / 互斥信号量, 一次只有一个线程访问缓冲int product_id =

14、 0; /生产者idint prochase_id = 0; /消费者id/* 打印缓冲情况 */void print()int i;for(i = 0; i M; i+) printf(%d , buffi);printf(n);/* 生产者方法 */ void *product()int id = +product_id;while(1) / 用sleep的数量可以调节生产和消费的速度,便于观察 sleep(1); /sleep(1); sem_wait(&empty_sem); pthread_mute*_lock(&mute*); in = in % M; printf(product

15、%d in %d. like: t, id, in); buffin = 1; print(); +in; pthread_mute*_unlock(&mute*); sem_post(&full_sem); /* 消费者方法 */void *prochase()int id = +prochase_id;while(1) / 用sleep的数量可以调节生产和消费的速度,便于观察 sleep(1);/sleep(1); sem_wait(&full_sem); pthread_mute*_lock(&mute*); out = out % M; printf(prochase%d in %d.

16、 like: t, id, out); buffout = 0; print(); +out; pthread_mute*_unlock(&mute*); sem_post(&empty_sem);int main()pthread_t id1N;pthread_t id2N;int i;int retN;/ 初始化同步信号量int ini1 = sem_init(&empty_sem, 0, M); int ini2 = sem_init(&full_sem, 0, 0); if(ini1 & ini2 != 0) printf(sem init failed n); e*it(1); /初

17、始化互斥信号量 int ini3 = pthread_mute*_init(&mute*, NULL);if(ini3 != 0) printf(mute* init failed n); e*it(1); / 创立N个生产者线程for(i = 0; i N; i+) reti = pthread_create(&id1i, NULL, product, (void *)(&i); if(reti != 0) printf(product%d creation failed n, i); e*it(1); /创立N个消费者线程for(i = 0; i N; i+) reti = pthread_create(&id2i, NULL, prochase, NULL); if(reti != 0) printf(prochase%d creation failed n, i); e*it(1); /销毁线程for(i = 0; i N; i+) pthread_join(id1i,NULL); pthread_join(i

温馨提示

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

评论

0/150

提交评论