zoukankan      html  css  js  c++  java
  • 信号量实现生产者消费者问题

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

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

    一个仓库空间,消费者在仓库产品为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;
    }
  • 相关阅读:
    BZOJ 1013--[JSOI2008]球形空间产生器sphere(高斯消元)
    BZOJ 1012--[JSOI2008]最大数maxnumber(二分&单调栈)
    BZOJ 3357--[Usaco2004]等差数列(STL&DP)
    BZOJ 1011--[HNOI2008]遥远的行星(乱搞)
    BZOJ 1010--[HNOI2008]玩具装箱toy(斜率优化dp)
    BZOJ 5334--[Tjoi2018]数学计算(线段树)
    BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
    BZOJ 1008--[HNOI2008]越狱(容斥&快速幂)
    一个典型的装饰器
    Nginx 配置文件详解
  • 原文地址:https://www.cnblogs.com/XNQC1314/p/9164821.html
Copyright © 2011-2022 走看看