IPC-信号灯之生产者消费者
有亲缘关系生产者消费者
子进程生成,父进程消费
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<stdlib.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int main(void)
{
int semid = semget(0, 1, 0666|IPC_CREAT);// 0为IPC_PRIVATE表示该信号灯集在父子进程间,1表示信号灯集有1个信号灯
if(-1 == semid)
{
perror("semget");
exit(EXIT_FAILURE);
}
union semun sm;
sm.val = 5; // sm.val表示某个信号灯的起始资源数量
if(-1 == semctl(semid, 0, SETVAL, sm)) // 将sm写到下标为0的信号灯(semid所标识的信号灯集)中
{
perror("semctl");
exit(EXIT_FAILURE);
}
if(fork() == 0) // 子进程为生产者
{
struct sembuf sop;
sop.sem_num = 0; // 下标为0的信号灯
sop.sem_op = 1; // V操作
sop.sem_flg = 0; // 0代表资源不足则阻塞
while(1)
{
sleep(3);
if(-1 == semop(semid, &sop, 1)) // 1表示sembuf数组(sop)大小为1
{
perror("semop");
exit(EXIT_FAILURE);
}
printf("V 资源数量:%d\n", semctl(semid, 0, GETVAL, sm));
}
return 0;
}
// 消费者
struct sembuf sop;
sop.sem_num = 0;
sop.sem_op = -1;
sop.sem_flg = 0;
while(1)
{
if(-1 == semop(semid, &sop, 1))
{
perror("semop");
exit(EXIT_FAILURE);
}
printf("P 资源数量:%d\n", semctl(semid, 0, GETVAL));
sleep(1);
}
return 0;
}
无亲缘关系
问题描述:一个仓库能装下10个产品。仓库装满之后,生产者停止生产,等待仓库非满;仓库空之后,消费者停止消费,等待仓库非空
producer.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/sem.h>
#include<sys/ipc.h>
//生产者消费者之间设置相同且唯一的KEY,以便获取相同的semid,最好用ftok获取,以便保证唯一性
#define KEY 1234
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int createSemSet(int nsems, int semflg)
{
int semid;
semid = semget(KEY, nsems, semflg);
if(-1 == semid)
{
perror("semget");
exit(EXIT_FAILURE);
}
return semid;
}
int semctlSetall(int semid)
{
unsigned short arr[2];
arr[0] = 0; // 仓库初始库存
arr[1] = 10; // 仓库剩余空间
union semun sm;
sm.array = arr;
int returnValue = semctl(semid, 0, SETALL, sm);
if(-1 == returnValue)
{
perror("semctl SETALL");
exit(EXIT_FAILURE);
}
return returnValue;
}
void init2Sembuf(struct sembuf *sops)
{
sops[0].sem_num = 0;
sops[0].sem_op = 1; // V操作
sops[0].sem_flg = 0;// 资源不足则阻塞
sops[1].sem_num = 1;
sops[1].sem_op = -1;// P操作
sops[1].sem_flg = 0;
}
int main(void)
{
int semid;
semid = createSemSet(2, IPC_CREAT|0666);
semctlSetall(semid);
struct sembuf sops[2];
init2Sembuf(sops);
while(1)
{
printf("--productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
sleep(2);
if(-1 == semop(semid, sops, 2))
{
perror("semop");
exit(EXIT_FAILURE);
}
printf("productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
}
return 0;
}
customer.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/sem.h>
#include<sys/ipc.h>
#define KEY 1234
int createSemSet(int nsems, int semflg)
{
int semid;
semid = semget(KEY, nsems, semflg);
if(-1 == semid)
{
perror("semget");
exit(EXIT_FAILURE);
}
return semid;
}
void init2Sembuf(struct sembuf *sops)
{
sops[0].sem_num = 0;
sops[0].sem_op = -1;
sops[0].sem_flg = 0;
sops[1].sem_num = 1;
sops[1].sem_op = 1;
sops[1].sem_flg = 0;
}
int main(void)
{
int semid;
semid = createSemSet(2, IPC_CREAT|0666);
struct sembuf sops[2];
init2Sembuf(sops);
while(1)
{
printf("--productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
sleep(1);
if(-1 == semop(semid, sops, 2))
{
perror("semop");
exit(EXIT_FAILURE);
}
printf("productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
}
return 0;
}