信号量实现生产者消费者问题

  生产消费问题是一个经典的数学问题,要求生产者---消费者在固定的仓库空间条件下,生产者每生产一个

产品将占用一个仓库空间,生产者生产的产品库存不能越过仓库的存储量,消费者每消费一个产品将增加

一个仓库空间,消费者在仓库产品为0时不能再消费。

   以下使用了两个信号量,一个用来管理消费者即sem_produce,另一个用来管理生产者即sem_custom,

sem_produce表示当前仓库可用空间的数量,sem_custom用来表示当前仓库中产品的数量。

  • 对于生产者来说,其需要申请的资源为仓库中的剩余空间,因此,生产者在生产一个产品前需要申请

sem_produce信号量。当此信号量的值大于0,即有可用空间,将生产产品,并将sem_produce的值减去1

(因为占用了一个空间);同时,当其生产一个产品后,当前仓库的产品数量增加1,需要将sem_custom信号

量自动加1。

  • 对于消费者来说,其需要申请的资源为仓库中的产品,因此,消费者在消费一个产品前将申请sem_cu

stom信号量。当此信号量的值大于0时,即有可用产品,将消费一个产品,并将sem_custom信号量的值减

去1(因为消费了一个产品);同时,当消费一个产品,当前仓库的剩余空间增加1,需要将sem_produce信号

量自动加1。

  下面是生产者端的代码:

//sem_productor.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/sem.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>

int sem_id;
void init()
{
    key_t key;
    int ret;
    unsigned short sem_array[2];
    union semun
    {
        int val;
        struct semid_ds *buf;
        unsigned short *array;
    }arg;
    key= ftok("mysem",'s');
    sem_id= semget(key,2,IPC_CREAT|0644);
    sem_array[0]= 0;
    sem_array[1]= 100;
    arg.array= sem_array;
    ret= semctl(sem_id,0,SETALL,arg);
    if(ret== -1)
    {
        printf("SETALL failed (%d)\n",errno);
    }
    printf("productor init is %d\n",semctl(sem_id,0,GETVAL));
    printf("space init is %d\n\n",semctl(sem_id,1,GETVAL));
}

void del()
{
    semctl(sem_id,0,IPC_RMID);
}

int main(int argc,char *argv[])
{
    struct sembuf sops[2];
    sops[0].sem_num= 0;
    sops[0].sem_op= 1;
    sops[0].sem_flg= 0;

    sops[1].sem_num= 1;
    sops[1].sem_op= -1;
    sops[1].sem_flg= 0;
    init();
    printf("this is productor\n");
    while(1)
    {
        printf("\n\nbefore produce:\n");
        printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
        printf("space number is %d\n",semctl(sem_id,1,GETVAL));
        semop(sem_id,(struct sembuf*)&sops[1],1);
        printf("now producing...\n");
        semop(sem_id,(struct sembuf*)&sops[0],1);
        printf("\nafter produce\n");
        printf("space number is %d\n",semctl(sem_id,1,GETVAL));
        printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
        sleep(2);
    }
    del();
    return 0;
}

   下面是消费者端的代码:

//sem_customer.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>

int sem_id;
void init()
{
    key_t key;
    key=ftok("mysem",'s');
    sem_id= semget(key,2,IPC_CREAT|0644);
}

int main(int argc,char *argv[])
{
    struct sembuf sops[2];
    sops[0].sem_num= 0;
    sops[0].sem_op= -1;
    sops[0].sem_flg= 0;

    sops[1].sem_num= 1;
    sops[1].sem_op= 1;
    sops[1].sem_flg= 0;
    init();
    printf("this is customer\n");
    while(1)
    {
        printf("\n\nbefore consume:\n");
        int ret= semctl(sem_id,0,GETVAL);
        int ret1= semctl(sem_id,1,GETVAL);
        printf("productor is %d\n",ret);
        printf("space is %d\n",ret1);
        semop(sem_id,(struct sembuf*)&sops[0],1);
        printf("now consuming...\n");
        semop(sem_id,(struct sembuf*)&sops[1],1);
        printf("\nafter consume\n");
        printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
        printf("space number is %d\n",semctl(sem_id,1,GETVAL));
        sleep(3);
    }
    return 0;
}

 

posted @ 2018-06-10 22:46  XNQC  阅读(5599)  评论(0编辑  收藏  举报