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

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

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

一个仓库空间,消费者在仓库产品为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;
}

原文地址:https://www.cnblogs.com/XNQC1314/p/9164821.html

时间: 2024-10-17 21:41:36

信号量实现生产者消费者问题的相关文章

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

用信号量解决生产者消费者问题: ipc.h #ifndef _IPC_H_ #define _IPC_H_ #include <sys/types.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #include <errno.h> #include <stdio.h> #include <st

基于POSIX的信号量的生产者消费者模型

信号量和Mutex类似,表示可用资源的数量,和Mutex不同的是,这个数量可以大于1,即如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同. 下面我们看看POSIX semaphore库函数,它既可以用于同一进程的线程间同步,也可以用于不同进程间的同步. 1. int sem_init(sem_t *sem,int pshared,unsigned int value) 我们可以用此函数来创建一个未命名的信号量,pshared参数表明是否在多个进程中使用信号量,如果是,将其设置为非0 值,

Linux下用环形buf以及POSIX版本信号量解决生产者消费者问题

一.Semaphore(信号量) Mutex变量是非0即1的,可看作一种资源的可用数量,初始化时Mutex是1,表示有一个可用资源, 加锁时获得该资源,将Mutex减到0,表示不再有可用资源,解锁时释放该资源,将Mutex重新加到1,表示又有了一个可用资源. 信号量(Semaphore)和Mutex类似,表示可用资源的数量,和Mutex不同的是这个数量可以大于1. 即,如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同! 本次使用的是POSIX semaphore库函数,这种信号量不仅可以

【Windows】用信号量实现生产者-消费者模型

线程并发的生产者-消费者模型: 1.两个进程对同一个内存资源进行操作,一个是生产者,一个是消费者. 2.生产者往共享内存资源填充数据,如果区域满,则等待消费者消费数据. 3.消费者从共享内存资源取数据,如果区域空,则等待生产者填充数据. 4.生产者的填充数据行为和消费者的消费数据行为不可在同一时间发生. 下面用Windows的信号量以及线程等API模拟生产者-消费者模型 #include <Windows.h> #include <stdio.h> #define N 100 #d

用记录型信号量解决生产者-消费者问题

1 int in = 0, out = 0;//in: 输入指针, out: 输出指针; 2 item buffer[n];//n个缓冲区组成的数组; 3 semaphore mutex = 1, full = 0, empty = n; 4 //mutex: 互斥信号量, 生产者进程和消费者进程都只能互斥访问缓冲区; 5 //full: 资源信号量, 满缓冲区的数量; 6 //empty: 资源信号量, 空缓冲区的数量;//信号量不允许直接参与运算, 故都要定义; 7 8 //生产者程序; 9

Unix IPC之Posix信号量实现生产者消费者

采用多生产者,多消费者模型. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /**  * 生产者  */ P(nempty); P(mutex); // 写入一个空闲位置 V(mutex); V(nstored); /**  * 消费者  */ P(nstored); P(mutex): // 清空一个非空闲位置 V(mutex); V(nempty); 全局性说明: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)

本文主要内容: 信号量的实现 利用信号量解决哲学家用餐问题 利用信号量解决生产者消费者问题 一.信号量的实现 1.1 信号量结构 typedef struct { int value; struct process * list } semaphore; value代表当前信号量可以使用的数量,list代表当前信号量上所等待的进程. 1.2 P操作实现 P(semaphore * s) { s.value--; if(s.value < 0) { add current process to s

Linux多线程实践(5) --Posix信号量与互斥量解决生产者消费者问题

Posix信号量 Posix 信号量 有名信号量 无名信号量 sem_open sem_init sem_close sem_destroy sem_unlink sem_wait sem_post 有名信号量 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <semaphore.h> sem_t *sem_open(co

13 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把