信号量 --- 哲学家就餐

比如我们有一张桌子,上面坐着五位哲学家
这里写图片描述
现在他们每个人都有一双筷子,并且都拥有了自己的编号。
这里写图片描述
桌子上摆满了菜,哲学家们现在开始只做两件事情,吃饭,或者思考。
当他们吃饭的时候就停止思考 ,当他们思考的时候就停止吃饭。
我们假设他们都会用筷子,而当他们要吃饭的时候都必须拿两根筷子。
而且每个哲学家并不互相交流,此时就会出现一个很严重的问题。
如果这些哲学家在准备吃饭的时候,先拿起自己的筷子,再拿起自己左手边的筷子。当五名哲学家同时准备进餐的时候就会发现,自己的左手边都没有筷子可拿。此时就会产生死锁。

在这里,我们需要先了解死锁
死锁 :
死锁是指两个或两个以上的进程在执行过程中,由于资源竞争或彼此通信而造成的一种阻塞现象。若无外力作用,他们都将无法进行下去,此时称系统处于死锁状态或系统产生了死锁。
死锁产生的四个必要条件 :
1. 互斥
进程对所分配的资源进行排他性使用,即资源独占。如果有其他进程请求资源,那么其他进程只能等待,直到资源被释放。
2. 请求并保持
指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已经被占用。此时进程阻塞并对自己获得的其他资源不释放。
3. 不剥夺
进程获得的资源在未使用完前,不能被剥夺。只能通过进程自己释放。
4. 环路等待
发生死锁时,必须存在一个进程—资源的环形链。

例 :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
#include <time.h>

int semid;
union semun{
    int val;
};

void wait_for_1fork(int no)  // 取出一根筷子
{
    struct sembuf sbs[1] = {no, -1, 0};
    semop(semid, sbs, 1);
}

void philosophere( int no )
{  // 哲学家开始进行思考/吃饭
    srand(time(NULL));
    while( 1 ){
        sleep(rand()%3);
        printf("%d think\n", no);
        sleep(rand()%3);
        printf("%d hungry\n",no);
        wait_for_1fork(no);
        sleep(rand()%2);  // 间隔一段时间后拿起第二根筷子
        wait_for_1fork((no+1)%5);
        printf("%d eating\n",no);
        put_for_2fork(no);
    }
}
int main( void )
{
    srand(time(NULL));
    // 创建信号量
    semid = semget(IPC_PRIVATE, 5, IPC_PRIVATE|0666);
    if( semid == -1)
        perror("semget"),exit(1);

    union semun su;
    su.val = 1;
    int i;
    for(i=0; i<5; i++)
        semctl(semid, i ,SETVAL, su);
    int no = 0;
    for(i=1; i<5; i++){
    // 我们使用不同的五个进程来模拟五位哲学家
        pid_t pid = fork();
        if( pid == 0){
            no = i;
            break;
        }
    }
    philosophere(no);
}

这里写图片描述
可以看出,当哲学家们同时准备进行吃饭的时候,此时都在等待下左手边的筷子,而没有筷子可拿,便陷入了死锁状态。

为了解决这种情况。

我们可以先让哲学家 拿左手边的筷子,再拿自己的筷子,那

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值