使用多线程/进程和System V信号量解决生产者消费者问题:有一个长度为N的缓冲池(共享内存)被生产者和消费者共同使用。只要缓冲池未满,生产者就可以将消息送入缓冲池;只要缓冲池不空,消费者便可从缓冲池中取走一个消息。生产者向缓冲池放入消息的同时,消费者不能操作缓冲池,反之亦然。
时间: 2024-02-06 14:10:37 浏览: 56
以下是使用多线程/进程和System V信号量解决生产者消费者问题的代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define N 5
#define BUF_SIZE 1024
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
struct shared_buffer {
int in;
int out;
char buf[N][BUF_SIZE];
};
int sem_id;
struct shared_buffer *buffer;
void P(int sem_id, int sem_num) {
struct sembuf sembuf = {sem_num, -1, 0};
semop(sem_id, &sembuf, 1);
}
void V(int sem_id, int sem_num) {
struct sembuf sembuf = {sem_num, 1, 0};
semop(sem_id, &sembuf, 1);
}
void producer() {
char input[BUF_SIZE];
while (1) {
fgets(input, BUF_SIZE, stdin);
P(sem_id, 0); // wait for empty buffer
printf("Producer puts item: %s", input);
strcpy(buffer->buf[buffer->in], input);
buffer->in = (buffer->in + 1) % N;
V(sem_id, 1); // signal full buffer
}
}
void consumer() {
char output[BUF_SIZE];
while (1) {
P(sem_id, 1); // wait for full buffer
strcpy(output, buffer->buf[buffer->out]);
buffer->out = (buffer->out + 1) % N;
printf("Consumer gets item: %s", output);
V(sem_id, 0); // signal empty buffer
}
}
int main() {
int shmid;
key_t key = ftok(".", 'x');
if ((shmid = shmget(key, sizeof(struct shared_buffer), IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit(1);
}
if ((buffer = (struct shared_buffer *) shmat(shmid, NULL, 0)) == (struct shared_buffer *) -1) {
perror("shmat");
exit(1);
}
buffer->in = 0;
buffer->out = 0;
if ((sem_id = semget(key, 2, IPC_CREAT | 0666)) < 0) {
perror("semget");
exit(1);
}
union semun arg;
arg.val = N;
if (semctl(sem_id, 0, SETVAL, arg) < 0) { // set empty buffer count
perror("semctl");
exit(1);
}
arg.val = 0;
if (semctl(sem_id, 1, SETVAL, arg) < 0) { // set full buffer count
perror("semctl");
exit(1);
}
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
} else if (pid == 0) { // child process as producer
producer();
} else { // parent process as consumer
consumer();
}
return 0;
}
```
在此代码中,我们使用了System V信号量来实现生产者消费者问题的同步。我们创建了两个信号量,分别表示缓冲池中空闲位置的数量和已经存储的消息数量。
在生产者进程中,当缓冲池未满时,生产者将消息放入缓冲池,并且减少空闲位置的计数。在消费者进程中,当缓冲池不空时,消费者从缓冲池中取出消息,并且增加空闲位置的计数。
在代码中,P() 和 V() 函数分别实现了等待和信号操作。使用这些操作,我们可以避免竞态条件和死锁问题,实现了生产者消费者问题的同步。
最后,我们使用多线程或多进程来实现生产者和消费者的并发操作,从而实现高效的消息传输。
阅读全文