生产者消费者c语言代码_生产者消费者问题、父子进程、信号量(IPC机制):代码分享...
时间: 2023-06-19 13:03:14 浏览: 93
下面是一个简单的生产者消费者问题的 C 语言代码,使用了父子进程和信号量(IPC机制):
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define BUFFER_SIZE 10
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int sem_id;
struct sembuf sem_op;
int init_sem(int sem_value) {
int sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
if (sem_id == -1) {
perror("semget error");
exit(EXIT_FAILURE);
}
union semun sem_union;
sem_union.val = sem_value;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1) {
perror("semctl error");
exit(EXIT_FAILURE);
}
return sem_id;
}
void del_sem() {
if (semctl(sem_id, 0, IPC_RMID, 0) == -1) {
perror("semctl error");
exit(EXIT_FAILURE);
}
}
void sem_p() {
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1) {
perror("semop error");
exit(EXIT_FAILURE);
}
}
void sem_v() {
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1) {
perror("semop error");
exit(EXIT_FAILURE);
}
}
int main() {
int i, in = 0, out = 0;
int buffer[BUFFER_SIZE];
sem_id = init_sem(BUFFER_SIZE);
pid_t pid;
pid = fork();
if (pid == -1) {
perror("fork error");
exit(EXIT_FAILURE);
} else if (pid == 0) { // 生产者
for (i = 0; i < 100; i++) {
sem_p();
buffer[in] = i;
printf("producer: %d\n", buffer[in]);
in = (in + 1) % BUFFER_SIZE;
sem_v();
}
} else { // 消费者
for (i = 0; i < 100; i++) {
sem_p();
printf("consumer: %d\n", buffer[out]);
out = (out + 1) % BUFFER_SIZE;
sem_v();
}
del_sem();
}
return 0;
}
```
上述代码中,`init_sem` 函数用于初始化信号量,`del_sem` 函数用于删除信号量,`sem_p` 函数用于执行 P 操作(信号量减 1),`sem_v` 函数用于执行 V 操作(信号量加 1)。
生产者进程和消费者进程的逻辑都比较简单,它们都通过 `sem_p` 和 `sem_v` 函数对信号量进行操作,从而实现互斥和同步。其中,生产者进程将数字写入到循环队列的队尾,消费者进程从队头读取数字。如果队列已满,生产者进程将会阻塞,直到队列不满为止;如果队列已空,消费者进程将会阻塞,直到队列不空为止。
需要注意的是,由于父子进程之间共享数据段,因此需要使用 IPC 机制(信号量、共享内存等)进行进程间通信。在本例中,我们使用了信号量来实现互斥和同步。在生产者进程和消费者进程之间共享的循环队列中,我们使用了数组来实现,因为数组的访问速度比链表快。
阅读全文