📅  最后修改于: 2023-12-03 15:22:22.252000             🧑  作者: Mango
本文将介绍如何使用信号量来解决生产者-消费者问题,并且设置缓冲区大小为1。生产者-消费者问题是一个经典的并发问题,生产者和消费者同时执行,生产者往缓冲区中放入数据,而消费者从缓冲区中取出数据。如果生产者向缓冲区中放入数据而缓冲区已满,生产者需要等待消费者从缓冲区中取走一个数据后,才能继续往缓冲区中放入数据;同样的,如果消费者从缓冲区中取出数据而缓冲区为空,消费者需要等待生产者往缓冲区中放入数据后,才能继续从缓冲区中取出数据。这个问题可以使用信号量来解决。
我们需要定义三个信号量:一个用于表示缓冲区是否为空,一个用于表示缓冲区是否已满,一个用于互斥,防止多个线程同时对缓冲区进行操作。
#include <semaphore.h>
#include <pthread.h>
sem_t full; //缓冲区是否已满
sem_t empty; //缓冲区是否为空
sem_t mutex; //互斥锁
初始化这三个信号量:
sem_init(&full, 0, 0);
sem_init(&empty, 0, 1);
sem_init(&mutex, 0, 1);
我们需要定义一个缓冲区,以及生产者和消费者线程,它们从缓冲区中取出和放入数据。
int buffer; //缓冲区
pthread_t producer_tid, consumer_tid;
void *producer(void *arg) {
int i;
for (i = 0; i < 10; i++) {
sem_wait(&empty); //缓冲区是否为空
sem_wait(&mutex); //互斥锁
buffer = i;
sem_post(&mutex); //互斥锁
sem_post(&full); //缓冲区是否已满
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
int i;
for (i = 0; i < 10; i++) {
sem_wait(&full); //缓冲区是否已满
sem_wait(&mutex); //互斥锁
int value = buffer;
sem_post(&mutex); //互斥锁
sem_post(&empty); //缓冲区是否为空
printf("Consumed: %d\n", value);
}
pthread_exit(NULL);
}
在main函数中创建线程,并等待线程结束。
int main() {
pthread_create(&producer_tid, NULL, producer, NULL);
pthread_create(&consumer_tid, NULL, consumer, NULL);
pthread_join(producer_tid, NULL);
pthread_join(consumer_tid, NULL);
return 0;
}
其中,sem_wait(&full)和sem_wait(&empty)会阻塞线程,等待信号量的值变成非零值。当信号量的值大于0时,它会将信号量的值减1。而sem_post(&full)和sem_post(&empty)会增加信号量的值。sem_wait(&mutex)和sem_post(&mutex)用于互斥,只有当互斥锁处于已解锁状态才能修改共享资源。
在本文中,我们介绍了如何使用信号量来解决生产者-消费者问题,设置缓冲区大小为1。信号量是一种用于进程或线程间同步与通信的基本工具,使得程序能够安全地访问共享资源,避免了数据竞争的问题。