用C语言编程实现生产者-消费者进程的同步与互斥,题目要求: 1、至少支持两个生产者和两个消费者; 2、每次只能有一个生产者或消费者进入仓库; 3、仓库满时生产者不能进入仓库,仓库空时消费者不能进入仓库。
时间: 2023-12-30 21:03:06 浏览: 81
生产者-消费者.doc
以下是一个基于进程的生产者-消费者模型的 C 语言代码,使用信号量实现同步和互斥:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/mman.h>
#define BUFFER_SIZE 10
typedef struct {
int buffer[BUFFER_SIZE];
int count;
sem_t *mutex;
sem_t *full;
sem_t *empty;
} shared_data;
shared_data *init_shared_data() {
int fd = shm_open("/shm", O_CREAT | O_RDWR, 0666);
if (fd == -1) {
perror("shm_open failed");
exit(EXIT_FAILURE);
}
int res = ftruncate(fd, sizeof(shared_data));
if (res == -1) {
perror("ftruncate failed");
exit(EXIT_FAILURE);
}
shared_data *data = mmap(NULL, sizeof(shared_data), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
perror("mmap failed");
exit(EXIT_FAILURE);
}
data->count = 0;
data->mutex = sem_open("/mutex", O_CREAT | O_RDWR, 0666, 1);
data->full = sem_open("/full", O_CREAT | O_RDWR, 0666, 0);
data->empty = sem_open("/empty", O_CREAT | O_RDWR, 0666, BUFFER_SIZE);
if (data->mutex == SEM_FAILED || data->full == SEM_FAILED || data->empty == SEM_FAILED) {
perror("sem_open failed");
exit(EXIT_FAILURE);
}
return data;
}
void destroy_shared_data(shared_data *data) {
sem_close(data->mutex);
sem_close(data->full);
sem_close(data->empty);
munmap(data, sizeof(shared_data));
shm_unlink("/shm");
sem_unlink("/mutex");
sem_unlink("/full");
sem_unlink("/empty");
}
void produce(shared_data *data, int id) {
int i;
for (i = 0; i < 20; i++) {
sem_wait(data->empty);
sem_wait(data->mutex);
data->buffer[data->count++] = i;
printf("生产者 %d 生产: %d\n", id, i);
sem_post(data->mutex);
sem_post(data->full);
sleep(1);
}
}
void consume(shared_data *data, int id) {
int i;
for (i = 0; i < 20; i++) {
sem_wait(data->full);
sem_wait(data->mutex);
int data = data->buffer[--data->count];
printf("消费者 %d 消费: %d\n", id, data);
sem_post(data->mutex);
sem_post(data->empty);
sleep(1);
}
}
int main(int argc, char **argv) {
shared_data *data = init_shared_data();
pid_t pid1, pid2, pid3, pid4;
pid1 = fork();
if (pid1 == 0) {
produce(data, 1);
exit(EXIT_SUCCESS);
}
pid2 = fork();
if (pid2 == 0) {
produce(data, 2);
exit(EXIT_SUCCESS);
}
pid3 = fork();
if (pid3 == 0) {
consume(data, 1);
exit(EXIT_SUCCESS);
}
pid4 = fork();
if (pid4 == 0) {
consume(data, 2);
exit(EXIT_SUCCESS);
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
waitpid(pid3, NULL, 0);
waitpid(pid4, NULL, 0);
destroy_shared_data(data);
return 0;
}
```
本代码中使用了共享内存和信号量来实现进程间的同步和互斥。在共享内存中存储了缓冲区和三个信号量:一个用于保护缓冲区的互斥信号量,一个用于表示缓冲区已满的信号量,一个用于表示缓冲区已空的信号量。生产者进程在缓冲区未满时才能生产,消费者进程在缓冲区非空时才能消费,通过对信号量的操作来实现进程的同步和互斥。
阅读全文