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

Posted xnqc1314

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了信号量实现生产者消费者问题相关的知识,希望对你有一定的参考价值。

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

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

一个仓库空间,消费者在仓库产品为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)
",errno);
    }
    printf("productor init is %d
",semctl(sem_id,0,GETVAL));
    printf("space init is %d

",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
");
    while(1)
    {
        printf("

before produce:
");
        printf("productor number is %d
",semctl(sem_id,0,GETVAL));
        printf("space number is %d
",semctl(sem_id,1,GETVAL));
        semop(sem_id,(struct sembuf*)&sops[1],1);
        printf("now producing...
");
        semop(sem_id,(struct sembuf*)&sops[0],1);
        printf("
after produce
");
        printf("space number is %d
",semctl(sem_id,1,GETVAL));
        printf("productor number is %d
",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
");
    while(1)
    {
        printf("

before consume:
");
        int ret= semctl(sem_id,0,GETVAL);
        int ret1= semctl(sem_id,1,GETVAL);
        printf("productor is %d
",ret);
        printf("space is %d
",ret1);
        semop(sem_id,(struct sembuf*)&sops[0],1);
        printf("now consuming...
");
        semop(sem_id,(struct sembuf*)&sops[1],1);
        printf("
after consume
");
        printf("productor number is %d
",semctl(sem_id,0,GETVAL));
        printf("space number is %d
",semctl(sem_id,1,GETVAL));
        sleep(3);
    }
    return 0;
}

 

以上是关于信号量实现生产者消费者问题的主要内容,如果未能解决你的问题,请参考以下文章

使用信号量实现有限缓冲区的生产者和消费者问题(使用fork(),semget()等函数,能在GCC下运行)

生产者消费者模型

Linux多线程_(Posix信号量实现环形队列生产者消费者模型)

LINUX多线程(生产者消费者模型,POXIS信号量)

进程经典问题总结

进程经典问题总结