本文介绍多种同步方法来解决进程间通信问题,并给出模型的代码实现。
代码介绍
本文主要侧重于代码实现,若对互斥(mutex)以及死锁问题还不够熟悉,可以参考我这篇文章。
-
include <pthread.h>
- pthread_mutex_t
- 用于创建互斥(mutex)变量
- pthread_mutex_lock
- 用于对互斥加锁,防止其他进程(线程)进入临界区。
- pthread_create
- 用于创建临界区
- pthread_t
- 标识线程```
-
include <semaphore.h>
- sem_t
- 用于创建信号量变量
- sem_init
- 信号量初始化函数
- sem_wait
- 相当于Dijkstra的down操作
- sem_post
- 相当于Dijkstra的up操作
哲学家进餐问题
引言
对于问题的描述不过多介绍,可参考wiki。
最naive的想法就是哲学家先取左叉子,再取右叉,最后再依次放回就行。但很遗憾这种想法会造成死锁。想象一下:若在同一时刻所有的哲学家都同时拿起左叉,那他们再也拿不到右叉,导致程序在一直运行却又无法进行下去。
因此,我们很容易想到利用互斥(mutex)进行改进。我们将哲学家进餐的一系列动作都lock起来,这样的确能避免死锁,但这样也会导致同一时间只有一个进程在进餐(资源浪费),有没有更好的方法呢?
我们知道,若有n个哲学家,则最多n/2个哲学家同时进餐。我们可以首先利用mutex将取叉的动作lock住,同时检查周围的人是否正在进餐。这样,我们就需要一个数组来标识每个哲学家的状态。最后,我们把动作分解为take_forks,eat,think,put_forks
四个状态,其中需要特别注意take_forks和put_forks
。
代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>