设计一c语言程序,由一个进程创建三个子进程,三个子进程一个是生产者进程,两个是消费者进程,且要求: 1、父子进程都使用父进程创建的共享存储区进行通信,由生产者进程将一个数组中的十个数值发送到由5个缓冲区组成的共享内存中; 2、两个消费者进程轮流接收并输出这十个数值,同时将两个消费者进程读出的数值进行累加求和; 3、考虑生产者进程生产的速度和消费者进程速度
时间: 2023-06-24 11:05:51 浏览: 240
linux下分窗口同时显示三个并发进程的小程序
以下是一个基本的实现,其中使用了信号量来保证进程间的同步和互斥:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define SHM_SIZE 5
#define BUF_SIZE 10
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void 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 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);
}
int main() {
pid_t pid1, pid2, pid3;
int shmid, semid, *shmaddr, i;
union semun sem_union;
// 创建共享内存
shmid = shmget(IPC_PRIVATE, SHM_SIZE * sizeof(int), IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
exit(EXIT_FAILURE);
}
// 连接共享内存
shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (int *) -1) {
perror("shmat");
exit(EXIT_FAILURE);
}
// 初始化共享内存
for (i = 0; i < SHM_SIZE; i++) {
shmaddr[i] = 0;
}
// 创建信号量
semid = semget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
if (semid == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
// 初始化信号量
sem_union.val = 1;
for (i = 0; i < SHM_SIZE; i++) {
semctl(semid, i, SETVAL, sem_union);
}
// 创建生产者进程
pid1 = fork();
if (pid1 == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid1 == 0) {
// 生产者进程
for (i = 0; i < BUF_SIZE; i++) {
P(semid, SHM_SIZE - 1);
shmaddr[i % SHM_SIZE] = i;
V(semid, i % SHM_SIZE);
}
exit(EXIT_SUCCESS);
}
// 创建消费者进程1
pid2 = fork();
if (pid2 == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid2 == 0) {
// 消费者进程1
int sum = 0;
for (i = 0; i < BUF_SIZE / 2; i++) {
P(semid, i % SHM_SIZE);
sum += shmaddr[i % SHM_SIZE];
printf("Consumer1: %d\n", shmaddr[i % SHM_SIZE]);
V(semid, SHM_SIZE - 1);
}
printf("Consumer1 sum: %d\n", sum);
exit(EXIT_SUCCESS);
}
// 创建消费者进程2
pid3 = fork();
if (pid3 == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid3 == 0) {
// 消费者进程2
int sum = 0;
for (i = BUF_SIZE / 2; i < BUF_SIZE; i++) {
P(semid, i % SHM_SIZE);
sum += shmaddr[i % SHM_SIZE];
printf("Consumer2: %d\n", shmaddr[i % SHM_SIZE]);
V(semid, SHM_SIZE - 1);
}
printf("Consumer2 sum: %d\n", sum);
exit(EXIT_SUCCESS);
}
// 等待子进程结束
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
waitpid(pid3, NULL, 0);
// 删除共享内存
if (shmdt(shmaddr) == -1) {
perror("shmdt");
exit(EXIT_FAILURE);
}
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(EXIT_FAILURE);
}
// 删除信号量
if (semctl(semid, 0, IPC_RMID, sem_union) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
return 0;
}
```
在该实现中,父进程创建了共享内存和信号量,然后分别创建了生产者进程和两个消费者进程。生产者进程将数组中的十个数值写入由5个缓冲区组成的共享内存中,两个消费者进程轮流从缓冲区中读取数值并累加求和。同时,使用信号量来保证生产者和消费者之间的同步和互斥,确保生产者不会在缓冲区已满时写入,消费者不会在缓冲区为空时读取。最后,父进程等待所有子进程结束后删除共享内存和信号量。
阅读全文