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;
}