System V进程间通信--信号量机制(生产者消费者问题)

一、问题描述:
生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

代码实现:
Productor:

/*
 *运用信号量机制完成生产者消费者模型
 *此为生产者
 */

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<errno.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("." , '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\n" , semctl(sem_id , 0 , GETVAL)) ; //打印初始结果,产品数
    printf("space init is %d\n\n" , semctl(sem_id , 1 , GETVAL)) ; //空间数

}

void del()
{
    semctl(sem_id , IPC_RMID  , 0) ; //完成操作后删除,在此程序是一个死循环,不会执行此操作
}

int main(int argc , char* argv[])
{
    struct sembuf sops[2] ; //操作两个信号量所使用的结构体

    sops[0].sem_num  = 0 ;
    sops[0].sem_op = 1 ; //执行加1操作,每生产一个产品,对产品数加1
    sops[0].sem_flg = 0 ; 

    sops[1].sem_num = 1 ;
    sops[1].sem_op = -1 ; //执行减1操作,对空间数减1
    sops[1].sem_flg = 0 ; 

    init() ;

    printf("this is a 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\n" , semctl(sem_id , 1 , GETVAL)) ; 
        printf("product number is %d\n\n" , semctl(sem_id , 0 , GETVAL)) ; 
        sleep(4) ;
    }
    del() ;
    return 0 ;
}

Customer:

/*
 *运用信号量机制完成生产者消费者模型
 *此为消费者
 */

#include<stdio.h>
#include<unistd.h>
#include<stdlib.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("." , 's') ;
    sem_id = semget(key , 2 , IPC_CREAT | 0644) ; //产生信号量集合
}


int main(int argc , char* argv[])
{
    init() ;
    struct sembuf sops[2] ; //操作两个信号量所使用的结构体

    sops[0].sem_num  = 0 ;
    sops[0].sem_op = -1 ; //执行减1操作,每消费一个产品,对产品数减1
    sops[0].sem_flg = 0 ; 

    sops[1].sem_num = 1 ;
    sops[1].sem_op = 1 ; //执行加1操作,对空间数加1
    sops[1].sem_flg = 0 ; 

    init() ;

    printf("this is a customer \n") ;

    while(1)
    {
        printf("\n\nbefore consume:\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 consuming.......\n") ;

        semop(sem_id  , (struct sembuf*)&sops[0] , 1) ;

        printf("\nafter consume\n") ;

        printf("space number is %d\n\n" , semctl(sem_id , 1 , GETVAL)) ; 
        printf("product number is %d\n\n" , semctl(sem_id , 0 , GETVAL)) ; 
        sleep(4) ;
    }
    return 0 ;
}

查看结果:

Produtor:
这里写图片描述

Customer:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值