操作系统课留的一个小作业,上网搜也搜不到关键的知识,有哪位大佬帮忙看一下,可以打赏,么么。
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);
}
在以上代码中需要注意的是没有缓冲区溢出和置空,可以加入判断实现,如果是实际工程还需要考虑到数据的同步和互斥
以上望采纳!!!!