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

来源:互联网 发布:php 跨平台 编辑:程序博客网 时间:2024/05/29 12:49

一、问题描述:
生产者消费者问题(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:
这里写图片描述

1 0
原创粉丝点击