#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define BUFFER_SIZE 10
#define SHARED_MEMORY_KEY 1234
#define SEMAPHORE_KEY 5678
// 缓冲池结构
typedef struct {
int buffer[BUFFER_SIZE];
int in; // 生产者写入位置
int out; // 消费者读取位置
int count; // 缓冲区中的数据个数
} Buffer;
// 共享内存标识符和信号量集标识符
int shmid, semid;
// 初始化共享内存和信号量
void init() {
// 创建共享内存
shmid = shmget(SHARED_MEMORY_KEY, sizeof(Buffer), IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
exit(1);
}
// 附加共享内存
Buffer *buffer = (Buffer *) shmat(shmid, NULL, 0);
if (buffer == (Buffer *) -1) {
perror("shmat");
exit(1);
}
// 初始化缓冲池
buffer->in = 0;
buffer->out = 0;
buffer->count = 0;
// 分离共享内存
shmdt(buffer);
// 创建信号量集
semid = semget(SEMAPHORE_KEY, 1, IPC_CREAT | 0666);
if (semid == -1) {
perror("semget");
exit(1);
}
// 初始化信号量
if (semctl(semid, 0, SETVAL, 1) == -1) {
perror("semctl");
exit(1);
}
}
// 生产者进程
void producer() {
Buffer *buffer = (Buffer *) shmat(shmid, NULL, 0);
if (buffer == (Buffer *) -1) {
perror("shmat");
exit(1);
}
while (1) {
sleep(rand() % 5); // 模拟生产时间
sembuf op;
op.sem_num = 0;
op.sem_op = -1; // P操作
op.sem_flg = 0;
semop(semid, &op, 1); // 获取信号量
// 生产数据
int data = rand() % 100;
printf("Producer %d produced: %d\n", getpid(), data);
buffer->buffer[buffer->in] = data;
buffer->in = (buffer->in + 1) % BUFFER_SIZE;
buffer->count++;
op.sem_op = 1; // V操作
semop(semid, &op, 1); // 释放信号量
}
shmdt(buffer);
}
// 消费者进程
void consumer() {
Buffer *buffer = (Buffer *) shmat(shmid, NULL, 0);
if (buffer == (Buffer *) -1) {
perror("shmat");
exit(1);
}
while (1) {
sleep(rand() % 5); // 模拟消费时间
sembuf op;
op.sem_num = 0;
op.sem_op = -1; // P操作
op.sem_flg = 0;
semop(semid, &op, 1); // 获取信号量
// 消费数据
int data = buffer->buffer[buffer->out];
printf("Consumer %d consumed: %d\n", getpid(), data);
buffer->out = (buffer->out + 1) % BUFFER_SIZE;
buffer->count--;
op.sem_op = 1; // V操作
semop(semid, &op, 1); // 释放信号量
}
shmdt(buffer);
}
int main() {
init();
// 创建两个生产者进程
pid_t producer1_pid = fork();
if (producer1_pid == 0) {
producer();
exit(0);
} else if (producer1_pid == -1) {
perror("fork");
exit(1);
}
pid_t producer2_pid = fork();
if (producer2_pid == 0) {
producer();
exit(0);
} else if (producer2_pid == -1) {
perror("fork");
exit(1);
}
// 创建两个消费者进程
pid_t consumer1_pid = fork();
if (consumer1_pid == 0) {
consumer();
exit(0);
} else if (consumer1_pid == -1) {
perror("fork");
exit(1);
}
pid_t consumer2_pid = fork();
if (consumer2_pid == 0) {
consumer();
exit(0);
} else if (consumer2_pid == -1) {
perror("fork");
exit(1);
}
// 等待子进程结束
waitpid(producer1_pid, NULL, 0);
waitpid(producer2_pid, NULL, 0);
waitpid(consumer1_pid, NULL, 0);
waitpid(consumer2_pid, NULL, 0);
// 删除共享内存和信号量
shmctl(shmid, IPC_RMID, NULL);
semctl(semid, 0, IPC_RMID);
return 0;
}