使用共享内存实现生产者消费者,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 在生产后面要加个延时,让消费完。因为生产者程序结束后可能会释放,导致消费者暂停在最后一次上,会出现问题。