/***************************************************************************************************************************************************
*
*创建5个哲学家abcde。然后a哲学家要吃反,首先拿起左手边的筷子,然后观察右手边的筷子是否有人用,有则放下左手筷子,若无则吃饭。注意
*哲学家吃饭时不被打扰,然后下一个哲学家吃饭判断,b哲学家的左筷子被a用,所以b不能吃进行思考,依次判断一下几个哲学家能否吃饭,原则为
*判断左手筷子是否能用,不能用进行下一个哲学家吃饭判断,若左手能用则判断右手筷子是否能用,若能吃饭,若不能则放下左手筷子进行思考,进
*行下一个哲学家的吃饭判断,依次类推循环。
*
*运行命令为:
*#gcc read.c -o zhe -lpthread
*./zhe
*
***************************************************************************************************************************************************/
#include
#include
#include
#include
#include
#include
//筷子作为mutex
pthread_mutex_t chopstick[6]; //定义以筷子为锁的数组
void *eat_think(void *arg)
{
char phi = *(char *) arg; //将任意类型的指针*arg转换为类型为*char指针复制给phi
int left, right; //定义左右筷子的编号
switch (phi)
{
case 'A': //哲学家 A 左手筷子为5,右手筷子为1
left = 5;
right = 1;
break;
case 'B': //哲学家 B 左手筷子为1,右手筷子为2
left = 1;
right = 2;
break;
case 'C': //哲学家 C 左手筷子为2,右手筷子为3
left = 2;
right = 3;
break;
case 'D': //哲学家 D 左手筷子为3,右手筷子为4
left = 3;
right = 4;
break;
case 'E': //哲学家 E 左手筷子为4,右手筷子为5
left = 4;
right = 5;
break;
}
int i;
for (;;)
{
usleep(1000000); //思考,把进程挂起一段时间
pthread_mutex_lock(&chopstick[left]); //拿起左手的筷子,锁定互斥量,加锁(阻塞)
printf("Philosopher %c fetches chopstick %d\n", phi, left); //输出哲学家phi拿起啦左手边的筷子
if (pthread_mutex_trylock(&chopstick[right]) == EBUSY) //判断右手的筷子是否有人用, 再试一次获得对互斥量的锁定(非阻塞)
{ //拿起右手的筷子
pthread_mutex_unlock(&chopstick[left]); //如果右边筷子被拿走放下左手的筷子,解锁互斥量,解锁
continue; //如果此哲学家没能吃饭,验证下一个哲学家是否能吃饭,即跳出本次循环进行下次循环
}
// pthread_mutex_lock(&chopstick[right]); //拿起右手的筷子,如果想观察死锁,把上一句if注释掉,再把这一句的注释去掉
printf("Philosopher %c fetches chopstick %d\n", phi, right); //输出此哲学家又拿起了右手边的跨子
printf("Philosopher %c is eating.\n", phi); //输出此次的哲学家拿起啦一双筷子在吃饭
usleep(1000000); //吃饭,把进程挂起一段时间
pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子,解锁互斥量,解锁
printf("Philosopher %c release chopstick %d\n", phi, left); //打印此哲学家放下左手的筷子
pthread_mutex_unlock(&chopstick[right]); //放下左手的筷子,解锁互斥量,解锁
printf("Philosopher %c release chopstick %d\n", phi, right); //打印此哲学家放下右手的筷子
}
}
int main()
{
pthread_t A, B, C, D, E; //定义了5个哲学家
int i;
for (i = 0; i < 5; i++)
pthread_mutex_init(&chopstick[i], NULL); //初始化默认互斥锁属性的互斥锁数组chopstick[i],默认属性为快速互斥锁
pthread_create(&A, NULL, eat_think, "A"); //创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 A 线程函数eat_think,A是运行函数的参数
pthread_create(&B, NULL, eat_think, "B"); //创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 B 线程函数eat_think,B是运行函数的参数
pthread_create(&C, NULL, eat_think, "C"); //创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 C 线程函数eat_think,C是运行函数的参数
pthread_create(&D, NULL, eat_think, "D"); //创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 D 线程函数eat_think,D是运行函数的参数
pthread_create(&E, NULL, eat_think, "E"); //创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 E 线程函数eat_think,E是运行函数的参数
pthread_join(A, NULL); //等待线程标识符为 A 的eat_think线程函数结束
pthread_join(B, NULL); //等待线程标识符为 B 的eat_think线程函数结束
pthread_join(C, NULL); //等待线程标识符为 C 的eat_think线程函数结束
pthread_join(D, NULL); //等待线程标识符为 D 的eat_think线程函数结束
pthread_join(E, NULL); //等待线程标识符为 E 的eat_think线程函数结束
return 0;
}
阅读(3191) | 评论(1) | 转发(1) |