system V 共享内存和信号量的组合使用 实现生产者消费者问题

看到别人写的,可是不是我想要的形式,改写下。

先运行消费者进程


producer.c


#include<sys/types.h>

#include<sys/sem.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<time.h>
#include <stdlib.h>
#include <string.h>

#ifndef _SEMUN_H

#define _SEMUN_H

union semun {
        int val;                        /* value for SETVAL */
        struct semid_ds *buf;                /* buffer for IPC_STAT, IPC_SET */
        unsigned short int *array;         /* array for GETALL, SETALL */
        struct seminfo *__buf;                /* buffer for IPC_INFO */
};

#endif



#define MAXSHM 5 //定义缓冲区数组的下标变量个数
/* 定义3个信号量的内部标识 */
struct node{
    int array[MAXSHM];
    int fullid;
    int emptyid;
    int mutexid;
    int get;
}* pshare;
/* 主函数 */
int main()
{
    /* 定义共享内存的ID */
    int shid;
    /* 创建共享内存 */
    shid = shmget(1024, sizeof(struct node),  0666);
    /* 初始化共享内存 */
    pshare = (struct node *) shmat(shid, 0, 0);
    
    /* 定义信号量数据结构 */
    struct sembuf P, V;
    union semun arg;
    
    
    /* 初始化 P V操作 */
    P.sem_num = 0;
    P.sem_op = -1;
    P.sem_flg = SEM_UNDO;
    V.sem_num = 0;
    V.sem_op = 1;
    V.sem_flg = SEM_UNDO;
    
    /* 生产者进程 */
    
    int i = 0;
    int set = 0;
    while (i < 10)
    {
        semop(pshare->emptyid, &P, 1); //对 emptyid执行P操作
        semop(pshare->mutexid, &P, 1); //对 mutexid执行 P操作
        pshare->array[set % MAXSHM] = i;
        printf("Producer put number %d to No.%d\n",pshare->array[set%MAXSHM],set%MAXSHM);
        set++; //写计数加1
        semop(pshare->mutexid, &V, 1); //对mutexid执行 V 操作
        semop(pshare->fullid, &V, 1); //对fullid执行 V 操作
        i++;
    }
    sleep(3); //SLEEP 3秒,等待消费者进程执行完毕
    printf("Poducer if over\n");

    exit(0);

}



consumer.c


#include<sys/types.h>
#include<sys/sem.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<time.h>
#include <stdlib.h>
#include <string.h>

#ifndef _SEMUN_H

#define _SEMUN_H

union semun {
        int val;                        /* value for SETVAL */
        struct semid_ds *buf;                /* buffer for IPC_STAT, IPC_SET */
        unsigned short int *array;         /* array for GETALL, SETALL */
        struct seminfo *__buf;                /* buffer for IPC_INFO */
};

#endif



#define MAXSHM 5 //定义缓冲区数组的下标变量个数
/* 定义3个信号量的内部标识 */
struct node{
    int array[MAXSHM];
    int fullid;
    int emptyid;
    int mutexid;
    int get;
}* pshare;
/* 主函数 */
int main()
{
    /* 定义共享内存的ID */
    int shid;
    /* 创建共享内存 */
    shid = shmget(1024, sizeof(struct node), IPC_CREAT | 0666);
    /* 初始化共享内存 */
    pshare = (struct node *) shmat(shid, 0, 0);
    memset(pshare,0,sizeof(struct node));
    
    /* 定义信号量数据结构 */
    struct sembuf P, V;
    union semun arg;
    
    /* 创建信号量 */
    pshare->fullid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
    pshare->emptyid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
    pshare->mutexid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
    
    /*初始化信号量 */
    arg.val = 0; //初始时缓冲区中无数据
    if(semctl(pshare->fullid,0,SETVAL,arg)==-1)
        perror("semctl setval error");
    arg.val = MAXSHM; //初始时缓冲区中有5个空闲的数组元素
    if(semctl(pshare->emptyid,0,SETVAL,arg)==-1)
        perror("semctl setval error");
    arg.val = 1; //初始时互斥信号为1,允许一个进程进入
    if(semctl(pshare->mutexid,0,SETVAL,arg)==-1)
        perror("semctl setval error");
    
    /* 初始化 P V操作 */
    P.sem_num = 0;
    P.sem_op = -1;
    P.sem_flg = SEM_UNDO;
    V.sem_num = 0;
    V.sem_op = 1;
    V.sem_flg = SEM_UNDO;
    
    

    /* 消费者A进程 */
    if(fork()==0)
    {
        printf("ConsunerA is begin\n");
        while(1)
        {
            if(pshare->get==10)
                break;
            printf("in a\n");
            semop(pshare->fullid,&P,1); //对fullid执行 P 操作
            semop(pshare->mutexid,&P,1);//对mutexid执行 P 操作
            printf("The ConsumerA get number %d from No.%d\n",pshare->array[pshare->get%MAXSHM],(pshare->get)%MAXSHM);
            (pshare->get)++;//读计数加1
            semop(pshare->mutexid,&V,1);//对mutexid执行 V 操作
            semop(pshare->emptyid,&V,1);//对fullid执行 V 操作
            sleep(1);
        }
        printf("ConsunerA is over\n");
        exit(0);
    }
    else
    {
    /*消费者B进程 */
        if(fork()==0)
        {
            printf("ConsunerB is begin\n");
            while(1)
            {
                    if(pshare->get==10)
                        break;
                    printf("in b\n");
                    semop(pshare->fullid,&P,1); //对fullid执行 P 操作
                    semop(pshare->mutexid,&P,1);//对mutexid执行 P 操作
                    printf("The ConsumerB get number %d from No.%d\n",pshare->array[pshare->get%MAXSHM],(pshare->get)%MAXSHM);
                    (pshare->get)++;//读计数加1
                    semop(pshare->mutexid,&V,1);//对mutexid执行 V 操作
                    semop(pshare->emptyid,&V,1);//对emptyid执行 V 操作
                    sleep(1);
            }
            printf("ConsunerB is over\n");
            exit(0);
        }
    }
    /* 父进程返回后回收3个子进程 */
    wait(0);
    wait(0);
    
    
    /* 撤消3个信号量集 */
    semctl(pshare->emptyid, IPC_RMID, 0);
    semctl(pshare->fullid, IPC_RMID, 0);
    semctl(pshare->mutexid, IPC_RMID, 0);
    
    /* 断开并撤消2个共享内存 */
    shmdt(pshare);
    shmctl(shid, IPC_RMID, 0);
    exit(0);
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值