qfedu-linux-advanced-level/day5/shm6.c

109 lines
2.3 KiB
C
Raw Permalink Normal View History

2023-08-18 16:47:04 +08:00
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/wait.h>
typedef struct data
{
int data;
int flag;
} Data;
int main()
{
key_t key = ftok("/", 28);
int shmid = shmget(key, sizeof(Data), IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
if (fork() == 0) // 生产者进程
{
Data *data = shmat(shmid, NULL, 0);
if (data == (Data *)-1)
{
perror("shmat");
return 1;
}
data->flag = 0; // 初始化为 0
data->data = 0; // 初始化为 0
for (int i = 0; i < 100; i++)
{
// 等待消费者消费数据
while (data->flag == 1)
;
data->data++; // 生产数据
data->flag = 1;
printf("生产者生产数据:%d\n", data->data);
}
// 解除映射
if (shmdt(data) == -1)
{
perror("shmdt");
return 1;
}
_exit(0); // 子进程退出
}
if (fork() == 0) // 消费者进程
{
Data *data = shmat(shmid, NULL, 0);
if (data == (Data *)-1)
{
perror("shmat");
return 1;
}
data->flag = 0; // 初始化为 0
data->data = 0; // 初始化为 0
for (int i = 0; i < 100; i++)
{
// 等待生产者生产数据
while (data->flag == 0)
{
printf("等待生产者生产数据\n");
}
printf("消费者消费数据:%d\n", data->data);
// 消费到 100 时退出
if (data->data == 10)
break;
sleep(1);
data->flag = 0;
}
// 解除映射
if (shmdt(data) == -1)
{
perror("shmdt");
return 1;
}
_exit(0); // 子进程退出
}
while (1)
{
// WUNTRACED 不跟踪 ?
int pid = waitpid(0, NULL, WUNTRACED);
if (pid == -1)
{
break;
}
printf("%d 子进程结束\n", pid);
}
// 删除共享内存
if (shmctl(shmid, IPC_RMID, NULL) == -1)
{
perror("shmctl");
return 1;
}
return 0;
}