linux 使用共享内存实现生产者消费者,PV操作。

使用共享内存实现生产者消费者,PV操作。


消费者的程序:

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

#define BUF_SIZE 100

union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

struct product
{
    int num;
    char buf[BUF_SIZE];
};

int main()
{
    int shm_id;
    char * adr;
    struct product * p1;
    int i;
    union semun sem_union;
    int sem_id;
    struct sembuf sops;

    shm_id = shmget((key_t)1234,sizeof(struct product),IPC_CREAT);
    if(-1 == shm_id)
    {
        printf("shmget error\n");
        exit(1);
    }
    
    adr = shmat(shm_id,NULL,0);
    if(-1 == (int)adr)
    {
        printf("shmat error\n");
        exit(1);
    }
    p1 = (struct product *)adr;


    sem_id = semget(ftok(".",1),2,0666|IPC_CREAT);
    if(-1 == sem_id)
    {
        printf("semget error\n");
        exit(1);
    }
#if 0 
    sem_union.val = 0;
    if(semctl(sem_id,0,SETVAL,sem_union) == -1)
    {
        printf("semctl error\n");
        exit(1);
    }
 
    sem_union.val = 1;
    if(semctl(sem_id,1,SETVAL,sem_union) == -1)
    {
        printf("setval error\n");
        exit(1);
    }
#endif

    for(i = 0; i < 5; i++)
    {
        sops.sem_num = 0;
        sops.sem_op = -1;
        sops.sem_flg = SEM_UNDO;
        if(-1 == semop(sem_id,&sops,1))
        {
              printf("semop error\n");
        }


        p1->num--;
        printf("%d\n",p1->num);
        printf("消费:%s\n",p1->buf);
        sops.sem_num = 1;
        sops.sem_op = +1;
        semop(sem_id,&sops,1);
        sleep(1);
    }

    if(semctl(sem_id,0,IPC_RMID,sem_union) == -1)
    {
        printf("semid error\n");
    }
   
    if(-1 == shmdt(adr))
    {
        printf("shmdt error\n");
        exit(1);
    }

    return 0;
}

生产者的和消费者差不多。


我在写这个的时候遇到三个问题。

1 在我一开始没有删除信号量的时候,创建有两个信号量的,就会不成功。嗯小问题。

2 如果两边都初始化的话,先运行生产者,消费者就会少消费一次。是因为程序阻塞在生产一次的上面的时候,再初始化就会又生产一次,就会出问题。所以只能初始化一次。

3 在生产后面要加个延时,让消费完。因为生产者程序结束后可能会释放,导致消费者暂停在最后一次上,会出现问题。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值