在linux下创建三个生产进程一个消费者进程共享长度为10KB的环形公共缓冲区,描述代码注释等

操作系统课留的一个小作业,上网搜也搜不到关键的知识,有哪位大佬帮忙看一下,可以打赏,么么。

1.创建共享内存:

#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_SIZE 10240 // 共享内存大小

int shmid;
char *shm;

shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT|0666); // 创建共享内存
shm = shmat(shmid, NULL, 0); // 获取共享内存指针

2.创建信号量

#include <sys/sem.h>

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int semid;

union semun sem_arg;
unsigned short sem_init_val[] = {0, 0, 0, 0};

semid = semget(IPC_PRIVATE, 4, IPC_CREAT|0666); // 创建信号量
sem_arg.array = sem_init_val;
semctl(semid, 0, SETALL, sem_arg); // 设置信号量初值

四个信号量,分别用于控制生产者进程、消费者进程、空闲缓冲区和已占用缓冲区的数量。
3.生产者进程实现

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define BUFFER_SIZE 1024 // 生产缓冲区大小

int in = 0; // 缓冲区写指针
int p_id; // 进程编号

void producer() {
    char *buffer = (char *)malloc(BUFFER_SIZE * sizeof(char));
    while (1) {
        sleep(rand() % 3); // 随机等待时间
        sem_p(semid, 2); // 等待空闲缓冲区
        sem_p(semid, p_id); // 等待本进程可用
        printf("Producer %d: Writing...\n", p_id);
        // 实现缓冲区写入
        for (int i = 0; i < BUFFER_SIZE; i++) {
            *(shm + in) = buffer[i];
            in = (in + 1) % SHM_SIZE;
        }
        sem_v(semid, 3); // 已占用缓冲区加1
        sem_v(semid, p_id); // 本进程可用加1
    }
}

int main() {
    // 初始化进程编号
    p_id = 1;

    // 创建三个生产者进程
    for (int i = 0; i < 3; i++) {
        pid_t pid = fork();
        if (pid == 0) {
            p_id += i;
            producer();
            exit(0);
        }
    }

    // 等待子进程退出
    while (wait(NULL) > 0);

    // 删除共享内存和信号量
    shmctl(shmid, IPC_RMID, NULL);
    semctl(semid, 0, IPC_RMID, sem_arg);

    return 0;
}

4.同理消费者进程实现

#include <unistd.h>
#include <stdio.h>

#define BUFFER_SIZE 1024 // 消费缓冲区大小

int out = 0; // 缓冲区读指针

void consumer() {
    char *buffer = (char *)malloc(BUFFER_SIZE * sizeof(char));
    while (1) {
        sleep(rand() % 3); // 随机等待时间
        sem_p(semid, 3); // 等待已占用缓冲区
        printf("Consumer: Reading...\n");
        // 实现缓冲区读取
        for (int i = 0; i < BUFFER_SIZE; i++) {
            buffer[i] = *(shm + out);
            out = (out + 1) % SHM_SIZE;
        }
        sem_v(semid, 2); // 空闲缓冲区加1
    }
}

int main() {
    // 创建一个消费者进程
    pid_t pid = fork();
    if (pid == 0) {
        consumer();
        exit(0);
    }

    // 等待子进程退出
    while (wait(NULL) > 0);

    // 删除共享内存和信号量
    shmctl(shmid, IPC_RMID, NULL);
    semctl(semid, 0, IPC_RMID, sem_arg);

    return 0;
}

5.信号量的P/V操作

void sem_p(int semid, int index) {
    struct sembuf sem;
    sem.sem_num = index;
    sem.sem_op = -1;
    sem.sem_flg = SEM_UNDO;
    semop(semid, &sem, 1);
}

void sem_v(int semid, int index) {
    struct sembuf sem;
    sem.sem_num = index;
    sem.sem_op = 1;
    sem.sem_flg = SEM_UNDO;
    semop(semid, &sem, 1);
}

在以上代码中需要注意的是没有缓冲区溢出和置空,可以加入判断实现,如果是实际工程还需要考虑到数据的同步和互斥
以上望采纳!!!!