有五个哲学家公用一张餐桌,分别坐在周围的五张椅子上,在餐桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和用餐。平时,一个哲学家进行思考,饥饿时便试图拿取其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐,进餐完毕,放下筷子继续思考。

思路:

选用互斥锁mutex,如创建5个, pthread_mutex_t m[5];
模型抽象:
5个哲学家 --> 5个线程; 5支筷子 --> 5把互斥锁 int left(左手), right(右手)
5个哲学家使用相同的逻辑,可通用一个线程主函数,void *tfn(void *arg),使用参数来表示线程编号:int i = (int)arg;
哲学家线程根据编号知道自己是第几个哲学家,而后选定锁,锁住,吃饭。否则哲学家thinking。
       A   B   C   D   E
5支筷子,在逻辑上形成环: 0   1   2   3   4   分别对应5个哲学家:


所以有:
if(i == 4)
left = i, right = 0;
else 
left = i, right = i+1;
振荡:如果每个人都攥着自己左手的锁,尝试去拿右手锁,拿不到则将锁释放。过会儿五个人又同时再攥着左手锁尝试拿右手锁,依然拿不到。如此往复形成另外一种极端死锁的现象——振荡。
避免振荡现象:只需5个人中,任意一个人,拿锁的方向与其他人相逆即可(如:E,原来:左:4,右:0 现在:左:0, 右:4)。
所以以上if else语句应改为:
if(i == 4)
left = 0, right = i;
else 
left = i, right = i+1;
而后, 首先应让哲学家尝试加左手锁:
while { 
pthread_mutex_lock(&m[left]); 如果加锁成功,函数返回再加右手锁,
如果失败,应立即释放左手锁,等待。
若,左右手都加锁成功 --> 吃 --> 吃完 --> 释放锁(应先释放右手、再释放左手,是加锁顺序的逆序)
}
主线程(main)中,初始化5把锁,销毁5把锁,创建5个线程(并将i传递给线程主函数),回收5个线程。
避免死锁的方法:
1. 当得不到所有所需资源时,放弃已经获得的资源,等待。
2. 保证资源的获取顺序,要求每个线程获取资源的顺序一致。如:A获取顺序1、2、3;B顺序应也是1、2、3。若B为3、2、1则易出现死锁现象。

代码:

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>pthread_mutex_t chopstick[5]; //5把锁,也就是5根筷子。void*tfn(void *arg)
{int i = (int)arg;int left,right;  //左右筷子的编号。if(i == 4){left = 0;right = i;}else{left = i;right = i+1;}while(1){sleep(1);  //思考pthread_mutex_lock(&chopstick[left]); //拿到左手的筷子。printf("philosopher %d fetches chopstick %d\n",i,left);if(pthread_mutex_trylock(&chopstick[right]) != 0 )//拿右手的筷子失败{pthread_mutex_unlock(&chopstick[left]); //右手筷子被拿走,放下左手的筷子。continue;}printf("philosopher %d fetches chopstick %d\n",i,right);printf("philosopher %d is eating.\n",i);sleep(2);  //吃饭pthread_mutex_unlock(&chopstick[right]); //放下右手的筷子。printf("philosopher %d release chopstick %d\n",i,right);pthread_mutex_unlock(&chopstick[left]); //放下右手的筷子。printf("philosopher %d release chopstick %d\n",i,left);}
}int main()
{pthread_t tid[5]; //5个哲学家int i ;for(i = 0; i < 5; ++i){pthread_mutex_init(&chopstick[i],NULL);pthread_create(&tid[i],NULL,tfn,(void*)i);}for( i = 0; i < 5; ++i){pthread_join(tid[i],NULL);}return 0;
}

Linux 多线程同步之哲学家用餐问题分析相关推荐

  1. linux多线程同步概览

    linux多线程同步概览 临界区 互斥锁 mutex 基本函数 pthread_mutex_destroy 何时调用? 互斥锁类型? 互斥量和自旋锁的区别 条件变量 condition variabl ...

  2. Linux多线程同步的几种方式

    线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 1)互斥锁(mutex) 通过锁机制实现线程间的 ...

  3. Linux多线程同步

    1 互斥锁 互斥锁用来保证一段时间内只有一个线程在执行一段代码.必要性显而易见:假设各个线程向同一个文件顺序写入数据,最后得到的结果一定是灾难性的. 先看下面一段代码.这是一个读/写程序,它们公用一个 ...

  4. Linux多线程同步------条件变量

    先来看下<Linux高性能服务器编程>中对条件变量的描述: 上述话可以总结为: 多线程中某一个线程依赖于另外一个线程对共享数据的改变时,就可以使用条件变量! 用消费者生产者的来理解条件变量 ...

  5. Linux 多线程同步机制:互斥量、信号量、条件变量

    互斥量:互斥量提供对共享资源的保护访问,它的两种状态:lock和unlock,用来保证某段时间内只有一个线程使用共享资源,互斥量的数据类型是pthread_mutex_t 主要涉及函数:pthread ...

  6. Linux多线程同步——信号量

    线程同步 同步主线程与子线程 test.c #include <pthread.h> #include <sys/syscall.h> #include <fcntl.h ...

  7. linux sem_wait sleep,[Linux]多线程同步之sem_wait()学习笔记

    1.semaphore 的这种信号量不仅可用于同一进程的线程同步,也可以用于不同进程间同步. 一个生产者-消费者例子:生产者不停的向一个固定大小的环形队列中添加数据,消费者从环形队列中清零数据,如果生 ...

  8. Linux多线程同步——互斥锁

    互斥锁 当多个线程对同一个资源进行访问的时候,为了这个资源的安全性,我们需要对这个资源进行锁定,规定同一时间只有一个资源能够获得该锁的钥匙,其它线程要获得该资源需要等待该线程 互斥锁创建 pthrea ...

  9. linux 线程间传送消息,Linux 多线程同步-消息队列

    消息队列是消息的链表,存放在内核中并有消息队列标示符标示. msgget用于创建一个新队列或打开一个现存的队列.msgsnd将新消息加入到消息队列中:每个消息包括一个long型的type:和消息缓存: ...

  10. linux 线程同步消息队列,Linux 多线程同步之消息队列

    消息队列是消息的链表,存放在内核中并有消息队列标示符标示. msgget用于创建一个新队列或打开一个现存的队列.msgsnd将新消息加入到消息队列中:每个消息包括一个long型的type:和消息缓存: ...

最新文章

  1. 什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?
  2. 从深圳回武汉的面试感想以及一些面试题
  3. python的优点-python的功能与优缺点
  4. Python 入门篇-最新版python3.7.2的安装。
  5. 噬血代码进不了游戏_玩家认可,二次元魂类游戏,《噬血代码》在三个方面做出了差异化...
  6. boost::tuple用法的测试程序
  7. 20个优秀的移动(iPhone)网站设计案例
  8. 数学是理工基础,如何才能令人信服?
  9. tomcat(15)Digester库
  10. python脚本监控mysql数据库_Python脚本监控mysql数据库,Python脚本监控mongo数据库
  11. camunda流程定义表无数据_创建流程实例时 act_ru_identitylink 表中没有出现相关的人员数据...
  12. Adobe Flash地图控件AnyMap
  13. winform基础,主要控件简单介绍,以及小练习
  14. 用n=4的复化Simpson公式求积分方程的近似解[matlab]
  15. Python学习笔记之基础练习(一)
  16. 【人月神话】浅谈人月神话0.1焦油坑
  17. 通用ESP8266连接阿里云物联网平台
  18. PostgreSQL汉字转拼音
  19. 禅与摩托车维修艺术摘录
  20. 拼多多店铺类型区别介绍

热门文章

  1. 轻量级云服务器部署K3S(公网部署)
  2. 让Thinkpad USB键盘支持小红帽中键滚轮的方法(ThinkPad USB Keyboard with TrackPoint)
  3. openwrt路由器samba拒绝访问
  4. PS 抠图如何使用通道法处理头发
  5. python 公众号引流_公众号粉丝从0到1000的引流思路
  6. 苹果笔记本如何打开计算机,苹果笔记本如何进入BIOS设置 Mac怎么设置BIOS
  7. 怎么在WORD2016里给文档空白处添加下划线,干货在这里,WORD2016空白处如何添加下划线
  8. c语言劝学,11劝学.doc
  9. 数据结构——查找与排序
  10. python如何安装pdfminer_Python 3.6 中使用pdfminer解析pdf文件的实现