生产者-消费者进程的同步与互斥c语言
时间: 2023-10-10 16:15:44 浏览: 102
生产者-消费者问题是一个经典的同步与互斥问题。在C语言中,可以使用信号量来实现同步与互斥,代码如下:
```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 // 消费者数量
#define PRODUCE_TIMES 5 // 生产者生产次数
#define CONSUME_TIMES 5 // 消费者消费次数
sem_t mutex; // 互斥信号量
sem_t empty; // 空缓冲区信号量
sem_t full; // 满缓冲区信号量
int buffer[BUFFER_SIZE]; // 缓冲区
int in = 0; // 生产者放置数据的位置
int out = 0; // 消费者取走数据的位置
void *producer(void *arg)
{
int id = *(int *)arg;
int i, item;
for (i = 0; i < PRODUCE_TIMES; i++) {
item = rand() % 100; // 随机生成数据
sem_wait(&empty); // 等待空缓冲区
sem_wait(&mutex); // 互斥访问缓冲区
buffer[in] = item; // 放置数据
printf("producer %d produces item %d\n", id, item);
in = (in + 1) % BUFFER_SIZE; // 更新in指针
sem_post(&mutex); // 释放互斥信号量
sem_post(&full); // 发送满缓冲区信号量
}
pthread_exit(NULL);
}
void *consumer(void *arg)
{
int id = *(int *)arg;
int i, item;
for (i = 0; i < CONSUME_TIMES; i++) {
sem_wait(&full); // 等待满缓冲区
sem_wait(&mutex); // 互斥访问缓冲区
item = buffer[out]; // 取走数据
printf("consumer %d consumes item %d\n", id, item);
out = (out + 1) % BUFFER_SIZE; // 更新out指针
sem_post(&mutex); // 释放互斥信号量
sem_post(&empty); // 发送空缓冲区信号量
}
pthread_exit(NULL);
}
int main()
{
pthread_t producers[PRODUCER_NUM];
pthread_t consumers[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM];
int consumer_ids[CONSUMER_NUM];
int i;
sem_init(&mutex, 0, 1); // 初始化互斥信号量
sem_init(&empty, 0, BUFFER_SIZE); // 初始化空缓冲区信号量
sem_init(&full, 0, 0); // 初始化满缓冲区信号量
// 创建生产者线程
for (i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i;
pthread_create(&producers[i], NULL, producer, &producer_ids[i]);
}
// 创建消费者线程
for (i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i;
pthread_create(&consumers[i], NULL, consumer, &consumer_ids[i]);
}
// 等待生产者线程结束
for (i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producers[i], NULL);
}
// 等待消费者线程结束
for (i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumers[i], NULL);
}
sem_destroy(&mutex); // 销毁互斥信号量
sem_destroy(&empty); // 销毁空缓冲区信号量
sem_destroy(&full); // 销毁满缓冲区信号量
return 0;
}
```
上述代码中,使用了三个信号量mutex、empty和full来实现同步与互斥。其中,mutex用于互斥访问缓冲区,empty用于表示缓冲区是否为空,full用于表示缓冲区是否满。在生产者和消费者的代码中,都需要先等待一个信号量,然后再进行操作,最后再发送一个信号量表示已完成操作。这样可以保证生产者和消费者之间的同步和互斥。
阅读全文