用信号量解决经典同步问题,生产者消费者问题及c语言代码示例
时间: 2023-08-22 22:05:11 浏览: 111
生产者消费者问题是一个经典的同步问题,可以通过信号量来解决。
信号量是一种同步机制,用于协调多个进程或线程之间的操作。它可以用来实现互斥、同步和通信等功能。在生产者消费者问题中,可以使用两个信号量来实现同步,一个用于表示有空闲的缓冲区可以写入,一个用于表示有数据可以读取。
以下是一个用信号量解决生产者消费者问题的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
#define PRODUCER_NUM 2
#define CONSUMER_NUM 2
sem_t empty, full, mutex;
int buffer[BUFFER_SIZE];
int in = 0, out = 0;
void *producer(void *arg)
{
int id = *((int *)arg);
while (1) {
int item = rand() % 100 + 1;
sem_wait(&empty);
sem_wait(&mutex);
buffer[in] = item;
printf("Producer %d produced item %d\n", id, item);
in = (in + 1) % BUFFER_SIZE;
sem_post(&mutex);
sem_post(&full);
sleep(rand() % 3);
}
pthread_exit(NULL);
}
void *consumer(void *arg)
{
int id = *((int *)arg);
while (1) {
sem_wait(&full);
sem_wait(&mutex);
int item = buffer[out];
printf("Consumer %d consumed item %d\n", id, item);
out = (out + 1) % BUFFER_SIZE;
sem_post(&mutex);
sem_post(&empty);
sleep(rand() % 3);
}
pthread_exit(NULL);
}
int main()
{
pthread_t producer_threads[PRODUCER_NUM], consumer_threads[CONSUMER_NUM];
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
int i, id[PRODUCER_NUM + CONSUMER_NUM];
for (i = 0; i < PRODUCER_NUM; i++) {
id[i] = i;
pthread_create(&producer_threads[i], NULL, producer, &id[i]);
}
for (i = 0; i < CONSUMER_NUM; i++) {
id[PRODUCER_NUM + i] = i;
pthread_create(&consumer_threads[i], NULL, consumer, &id[PRODUCER_NUM + i]);
}
for (i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producer_threads[i], NULL);
}
for (i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumer_threads[i], NULL);
}
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
```
在本示例代码中,empty、full和mutex是三个信号量,分别用于表示空闲缓冲区数、有数据缓冲区数和互斥访问缓冲区。在生产者线程中,先使用sem_wait(&empty)等待有空闲缓冲区可以写入,然后使用sem_wait(&mutex)获取互斥访问权,向缓冲区写入数据,然后释放互斥访问权和写入信号量full,并睡眠一段时间。在消费者线程中,先使用sem_wait(&full)等待有数据缓冲区可以读取,然后使用sem_wait(&mutex)获取互斥访问权,从缓冲区读取数据,然后释放互斥访问权和空闲信号量empty,并睡眠一段时间。
这样通过信号量的机制,就可以实现多个生产者和多个消费者并发地操作缓冲区,避免了数据竞争和死锁等问题。
阅读全文