#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<linux/sem.h>
int P(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
// 进行p操作
if (semop(sem_id, &sem_b, 1) == -1)
{
fprintf(stderr, "P failed\n");
return 0;
}
return 1;
}
int V(int sem_id) // 释放资源
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
// 进行v操作
if (semop(sem_id, &sem_b, 1) == -1)
{
fprintf(stderr, "V failed\n");
return 0;
}
return 1;
}
int main()
{
int i = 0;
int pid = 0;
int empty; // 盘子中是否为空
int full; // 盘子中是否为满
int apple; // 苹果有几个
int orange; // 橘子有几个
empty = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
if (semctl(empty, 0, SETVAL, 3) == -1) // 盘子中最多容纳3个水果
{
perror("semctl setval error");
}
full = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
if (semctl(full, 0, SETVAL, 0) == -1) // 盘子现在不满,且0个水果
{
perror("semctl setval error");
}
apple = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
if (semctl(apple, 0, SETVAL, 0) == -1)
{
perror("semctl setval error");
}
orange = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
if (semctl(orange, 0, SETVAL, 0) == -1)
{
perror("semctl setval error");
}
for (i = 0; i < 3; ++i)
{
pid = fork();
if (pid == 0)
{
while (1)
{
if (pid == 0 && i == 0)
{
P(empty);
if (rand() % 2 == 0)
{
printf("爸爸向盘子中放苹果\n");
V(apple);
V(full);
}
else
{
printf("爸爸向盘子中放橘子\n");
V(orange);
V(full);
}
sleep(2);
}
else if (pid == 0 && i == 1)
{
P(full);
P(apple);
printf("儿子从盘子中取走苹果\n");
V(empty);
sleep(2);
}
else if (pid == 0 && i == 2)
{
P(full);
P(orange);
printf("女儿从盘子中取走橘子\n", empty);
V(empty);
sleep(2);
}
}
}
}
return 0;
}
分析:
盘子中最多只能放3个水果,且儿子吃苹果,女儿吃橘子,因此建立四个信号量,两个表示盘中的水果数量空和满,一个表示苹果,一个表示橘子。
父亲先向盘子里放水果,随机选择苹果和橘子,放进去什么什么就多。当有苹果时,儿子就能拿走释放掉苹果和盘子里的水果数量。有橘子时女儿也相同。