实验名称:
姓名:
学号:
实验报告
专业:测控技术与仪器
P.1
姓名:颜睿
学号:3130103850
日期:2018.3.28
地点:创客空间
课程名称: 嵌入式系统设计
实验名称:哲学家就餐问题
一、实验目的和要求(必填)
三、主要仪器设备(必填)
五、实验数据记录和处理
七、讨论、心得
一、 实验目的和要求
指导老师:马永昌
成绩:________________
实验类型:验证型
同组学生姓名:__孙凡原_______
二、实验内容和原理(必填)
四、操作方法和实验步骤
六、实验结果与分析(必填)
1.加深对进\线程概念的理解。
2. 进一步认识死锁和资源耗尽及并发执行的实质。
3. 验证用信号量机制实现线程互斥的方法。
4. 验证用信号量机制实现线程同步的方法
二、实验内容和原理
实验内容:编程实现哲学家用餐问题,要求:
• 一个程序开 5 个进程或线程分别代表 5 个哲学家
• 显示哪些哲学家在用餐(eating),用了哪些叉子(注意显示输出也是 critical section 临界区)
• 以不作死锁防护的方式,让哲学家自由地作抢叉子,进食,发呆
• 人工观察,当发生死锁时,截图保存
• 尝试编程检测死锁,尝试不同的方式防护死锁(顺序资源法,加房间法,Psim 法)
装
订
线
三、主要仪器设备
PC 机、Ubuntu 虚拟机
四、操作方法和实验步骤
1.
test3.c (不做死锁防护)
2. #include
3. #include
4. #include
5. #include
6.
7. pthread_mutex_t chopstick[5] ;
8. void *eat_think(void *arg)
9. {
10.
char phi = *(char *)arg;
实验名称:
姓名:
学号:
P.2
int left,right;
switch (phi){
case 'A':
left = 1;
right = 2;
break;
case 'B':
left = 2;
right = 3;
break;
case 'C':
left = 3;
right = 4;
break;
case 'D':
left = 4;
right = 5;
break;
case 'E':
left = 5;
right = 1;
break;
装
订
线
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.}
50.int main(){
51.
52.
53.
54.
}
}
for(;;){
usleep(3);
pthread_mutex_lock(&chopstick[left-1]);
printf("Philosopher %c fetches chopstick %d\n", phi, left);
pthread_mutex_lock(&chopstick[right-1]);
printf("Philosopher %c fetches chopstick %d\n", phi, right);
printf("Philosopher %c is eating.\n",phi);
usleep(3);
pthread_mutex_unlock(&chopstick[left-1]);
printf("Philosopher %c release chopstick %d\n", phi, left);
pthread_mutex_unlock(&chopstick[right-1]);
printf("Philosopher %c release chopstick %d\n", phi, right);
pthread_t A,B,C,D,E;
int i;
for (i = 0; i < 5; i++)
实验名称:
姓名:
学号:
P.3
pthread_mutex_init(&chopstick[i],NULL);
pthread_create(&A,NULL, eat_think, "A");
pthread_create(&B,NULL, eat_think, "B");
pthread_create(&C,NULL, eat_think, "C");
pthread_create(&D,NULL, eat_think, "D");
pthread_create(&E,NULL, eat_think, "E");
pthread_join(A,NULL);
pthread_join(B,NULL);
pthread_join(C,NULL);
pthread_join(D,NULL);
pthread_join(E,NULL);
return 0;
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.}
装
订
线
2.test3_1.c (顺序资源法)
#include
#include
#include
#include
pthread_mutex_t chopstick[5] ;
void *eat_think(void *arg)
{
char phi = *(char *)arg;
int left,right;
switch (phi){
case 'A':
left = 1;
right = 2;
break;
case 'B':
left = 2;
right = 3;
break;
case 'C':
left = 3;
right = 4;
break;
case 'D':
left = 4;
right = 5;
实验名称:
姓名:
学号:
P.4
break;
}
for(;;){
usleep(1);
pthread_mutex_lock(&chopstick[left-1]);
printf("Philosopher %c fetches chopstick %d\n", phi, left);
pthread_mutex_lock(&chopstick[right-1]);
printf("Philosopher %c fetches chopstick %d\n", phi, right);
printf("Philosopher %c is eating.\n",phi);
usleep(1);
pthread_mutex_unlock(&chopstick[left-1]);
printf("Philosopher %c release chopstick %d\n", phi, left);
pthread_mutex_unlock(&chopstick[right-1]);
printf("Philosopher %c release chopstick %d\n", phi, right);
装
订
线
}
}
void *eat_think_E()
{
for(;;){
usleep(1);
pthread_mutex_lock(&chopstick[0]);
printf("Philosopher E fetches chopstick 1\n");
pthread_mutex_trylock(&chopstick[4]);
printf("Philosopher E fetches chopstick 5\n");
printf("Philosopher E is eating.\n");
usleep(1);
pthread_mutex_unlock(&chopstick[4]);
printf("Philosopher E release chopstick 5\n");
pthread_mutex_unlock(&chopstick[0]);
printf("Philosopher E release chopstick 1\n");
}
}
int main(){
pthread_t A,B,C,D,E;
int i;
for (i = 0; i < 5; i++)
pthread_mutex_init(&chopstick[i],NULL);
P.5
实验名称:
姓名:
学号:
pthread_create(&A,NULL, eat_think, "A");
pthread_create(&B,NULL, eat_think, "B");
pthread_create(&C,NULL, eat_think, "C");
pthread_create(&D,NULL, eat_think, "D");
pthread_create(&E,NULL, eat_think_E, NULL);
pthread_join(A,NULL);
pthread_join(B,NULL);
pthread_join(C,NULL);
pthread_join(D,NULL);
pthread_join(E,NULL);
return 0;
}
3.test3_2.c (加房间法)
#include
#include
#include
#include
#include
sem_t room_sem;
pthread_mutex_t chopstick[5] ;
void *eat_think(void *arg)
{
char phi = *(char *)arg;
int left,right;
switch (phi){
case 'A':
装
订
线
left = 1;
right = 2;
break;
case 'B':
left = 2;
right = 3;
break;
case 'C':
left = 3;
right = 4;
break;
case 'D':
left = 4;
right = 5;
实验名称:
姓名:
学号:
P.6
break;
case 'E':
left = 5;
right = 1;
}
for(;;){
usleep(1);
sem_wait(&room_sem);
pthread_mutex_lock(&chopstick[left-1]);
printf("Philosopher %c fetches chopstick %d\n", phi, left);
pthread_mutex_lock(&chopstick[right-1]);
printf("Philosopher %c fetches chopstick %d\n", phi, right);
printf("Philosopher %c is eating.\n",phi);
usleep(1);
pthread_mutex_unlock(&chopstick[left-1]);
printf("Philosopher %c release chopstick %d\n", phi, left);
pthread_mutex_unlock(&chopstick[right-1]);
printf("Philosopher %c release chopstick %d\n", phi, right);
sem_post(&room_sem);
装
订
线
}
}
int main(){
pthread_t A,B,C,D,E;
if(sem_init(&room_sem,0,4) != 0)
{
printf("sem init failed \n");
exit(1);
}
int i;
for (i = 0; i < 5; i++)
pthread_mutex_init(&chopstick[i],NULL);
pthread_create(&A,NULL, eat_think, "A");
pthread_create(&B,NULL, eat_think, "B");
pthread_create(&C,NULL, eat_think, "C");
pthread_create(&D,NULL, eat_think, "D");
pthread_create(&E,NULL, eat_think, "E");
实验名称:
姓名:
学号:
P.7
pthread_join(A,NULL);
pthread_join(B,NULL);
pthread_join(C,NULL);
pthread_join(D,NULL);
pthread_join(E,NULL);
sem_destroy(&room_sem);
return 0;
}
4.test3_3.c (P_sim 法)
#include
#include
#include
#include
#include
pthread_mutex_t mutex;
sem_t chopstick[5];
typedef struct Phi{
char id;
int left;
int right;
}Phi;
装
订
线
void P_sim(Phi p,sem_t *L,sem_t *R)
{
int L_value,R_value;
for(;;)
{
pthread_mutex_lock(&mutex);
if((sem_getvalue(L,&L_value)!=0) || (sem_getvalue(R,&R_value)!=0))
{
printf("get value failed \n");
exit(1);
}
if((L_value>0)&&(R_value>0))
{
sem_wait(L);
printf("Philosopher %c fetches chopstick %d\n", p.id, p.left);
实验名称:
姓名:
学号:
sem_wait(R);
printf("Philosopher %c fetches chopstick %d\n", p.id, p.right);
pthread_mutex_unlock(&mutex);
break;
P.8
}
else
{
pthread_mutex_unlock(&mutex);
}
//printf("Philosopher %c L_value:%d,R_value:%d\n",p.id,L_value,R_value);
}
}
void *eat_think(void *arg)
{
Phi ph = *(Phi *)arg;
for(;;){
usleep(1);
P_sim(ph,&chopstick[ph.left-1],&chopstick[ph.right-1]);
printf("Philosopher %c is eating.\n",ph.id);
usleep(1);
sem_post(&chopstick[ph.left-1]);
printf("Philosopher %c release chopstick %d\n", ph.id, ph.left);
sem_post(&chopstick[ph.right-1]);
printf("Philosopher %c release chopstick %d\n", ph.id, ph.right);
装
订
线
}
}
int main(){
pthread_t A,B,C,D,E;
Phi phi_1={.id='A', .left=1, .right=2};
Phi phi_2={.id='B', .left=2, .right=3};
Phi phi_3={.id='C', .left=3, .right=4};
Phi phi_4={.id='D', .left=4, .right=5};
Phi phi_5={.id='E', .left=5, .right=1};
if(pthread_mutex_init(&mutex,NULL) != 0)
{
printf("mutex init failed \n");
exit(1);