当前位置:文档之家› 实验二进程同步实验

实验二进程同步实验

实验二进程同步
一、实验目的:
掌握基本的同步算法,理解经典进程同步问题的本质;学习使用Linux的进程同步机制,掌握相关API的使用方法;能利用信号量机制,采用多种同步算法实现不会发生死锁的哲学家进餐程序。

二、实验平台:
虚拟机:VMWare9以上
操作系统:以上
编辑器:Gedit | Vim
编译器:Gcc
三、实验内容:
(1)以哲学家进餐模型为依据,在Linux控制台环境下创建5个进程,用semget函数创建一个信号量集(5个信号量,初值为1),模拟哲学家的思考和进餐行为:每一位哲学家饥饿时,先拿起左手筷子,再拿起右手筷子;筷子是临界资源,为每一支筷子定义1个互斥信号量;想拿到筷子需要先对信号量做P操作,使用完释放筷子对信号量做V操作。

伪代码描述:
semaphore chopstick[5]={1,1,1,1,1};
•第i位哲学家的活动可描述为:
do{
printf("%d is thinking\n",i);
printf("%d is hungry\n",i);
wait(chopstick[i]); 当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐;b.至多只允许有4位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐;c.规定奇数号哲学家先拿起他左手的筷子,然后再拿起他右手的筷子,而偶数号哲学家则先拿起他右手的筷子,然后再拿起他左手的筷子。

方法a在示例程序中给出,请用方法b和c写出不会发生死锁的哲学家进餐程序。

(3)设计程序,实现生产者/消费者进程(线程)的同步与互斥。

在该程序中创建4个进程(或线程)模拟生产者和消费者,实现进程(线程)的同步与互斥。

实验结果:
使用a方法结果哲学家就餐问题
使用b方法解决哲学家就餐问题源码如下:
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <sys/>
#include <sys/>
#include <sys/>
#include <sys/>
#include <sys/>
union semun
{
int val;
struct semid_ds *buf; unsigned short *array;
struct seminfo *_buf;
};
#define ERR_EXIT(m) \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)
like: \t", id, in);
buff[in] = 1;
print();
++in;
pthread_mutex_unlock(&mutex);
sem_post(&full_sem);
}
/* 消费者方法 */
void *prochase()
{
int id = ++prochase_id;
while(1)
{
like: \t", id, out);
buff[out] = 0;
print();
++out;
pthread_mutex_unlock(&mutex);
sem_post(&empty_sem);
}
}
int main()
{
pthread_t id1[N];
pthread_t id2[N];
int i;
int ret[N];
// 初始化同步信号量
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");
exit(1);
}
//初始化互斥信号量
int ini3 = pthread_mutex_init(&mutex, NULL);
if(ini3 != 0)
{
printf("mutex init failed \n");
exit(1);
}
// 创建N个生产者线程
for(i = 0; i < N; i++)
{
ret[i] = pthread_create(&id1[i], NULL, product, (void *)(&i));
if(ret[i] != 0)
{
printf("product%d creation failed \n", i);
exit(1);
}
}
//创建N个消费者线程
for(i = 0; i < N; i++)
{
ret[i] = pthread_create(&id2[i], NULL, prochase, NULL);
if(ret[i] != 0)
{
printf("prochase%d creation failed \n", i);
exit(1);
}
}
//销毁线程
for(i = 0; i < N; i++)
{
pthread_join(id1[i],NULL);
pthread_join(id2[i],NULL);
}
exit(0);
}
执行结果:
实验总结
哲学家进餐的问题
是操作系统信号量同步的经典例题了。

这次我通过解决哲学家进餐的哲学问题从而对进程同步有一个更好的理解,解决这个问题书中给出了三种解决方法。

我在实验中也是用这三种方法去定义信号量解决死锁问题。

通过信号量的获取与wait操作去控制进餐,a方法是控制哲学家左右手都有筷子时才能进餐,b中则是通过互斥信号量的获取,若没有信号量便不能执行,而且只有四个哲学家能同时进餐也避免了死锁的出现。

c中是让奇数的哲学家先拿左筷子执行wait和signal操作,偶数号的虽然也执行该操作但是只能拿右筷子。

相关主题