用信号量解决生产者消费者问题

代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <sys/wait.h>

union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
}

int semid;
#define DELAY (rand()%5+1)

int sem_p(int semid)
{
    struct sembuf sem_b;
    sem_b = {0,-1,SEM_UNDO};
    int ret;
    ret = semop(semid,&sem_b,1);
    if(ret == -1)
        exit(EXIT_FAILURE);
    return ret;
}

int sem_V(int semid)
{
    struct sembuf sem_b;
    sem_b = {0,1,SEM_UNDO};
    int ret;
    ret = semop(semid,&sem_b,1);
    if(ret == -1)
        exit(EXIT_FAILURE);
    return ret;
}

void wait_for_2fork(itn no)
{
    //对于每一个哲学家来说,他左边的叉子就是他的no. 右边的就是no+1;
    int left = no;
    int right = (no+1)%5;
    //获取资源
    struct sembuf buf[2] = {
        {left,-1,0},
        {right,-1,0}
    };
    semop(semid,buf,2);

}

void free_2fork(itn no)
{
    //对于每一个哲学家来说,他左边的叉子就是他的no. 右边的就是no+1;
    int left = no;
    int right = (no+1)%5;
    //获取资源
    struct sembuf buf[2] = {
        {left,1,0},
        {right,1,0}
    };
    semop(semid,buf,2);

}
void thinker(int no)
{
    for(;;)
    {
        printf("%d is thinking\n",no);
        sleep(DELAY);
        printf("%d is hungry\n",no);
        //进入临界区
        wait_for_2fork(no);
        printf("%d is eating\n",no);
        sleep(DELAY);
        //离开临界区
        free_2fork(no);

    }
}

int main(int argc, char *argv[])
{
    semid = semget(1234,5,0666 | IPC_CREAT);
    if(semid == -1)
        exit(EXIT_FAILURE);
    
    union semun su;
    su.val = 1;
    int i;
    for(i=0; i<5; i++)
    {
        semctl(semid,i,SETVAL,su);
    }

    int no = 0;
    pid_t pid;
    for(i=1; i<5; i++)
    {
            pid = fork();
            if(pid == -1)
                exit(EXIT_FAILURE);
            if(pid == 0)
            {
                no = i;
                break;
            }
    }
    //哲学家
    thinker(no);

    return 0;
}

 

posted @ 2017-03-30 17:11  ren_zhg1992  阅读(1030)  评论(0)    收藏  举报