c语言实现生产者/消费者进程(线程)的同步与互斥。在该程序中创建4个进程(或线程)模拟生产者和消费者,实现进程(线程)的同步与互斥。
时间: 2024-05-09 15:15:50 浏览: 132
以下是一个基于C语言实现生产者/消费者进程(线程)的同步与互斥的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10 // 缓冲区大小
#define PRODUCER_NUM 2 // 生产者线程数
#define CONSUMER_NUM 2 // 消费者线程数
sem_t mutex, empty, full; // 三个信号量
int buffer[BUFFER_SIZE]; // 缓冲区数组
int in = 0, out = 0; // 生产者和消费者的缓冲区指针
void *producer(void *arg)
{
int id = *(int *)arg;
while (1) {
int item = rand() % 100; // 随机生成一个生产的物品
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(1); // 等待一段时间再生产下一个物品
}
}
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(2); // 等待一段时间再消费下一个物品
}
}
int main()
{
srand(time(NULL));
sem_init(&mutex, 0, 1); // 初始化互斥信号量
sem_init(&empty, 0, BUFFER_SIZE); // 初始化空信号量
sem_init(&full, 0, 0); // 初始化满信号量
pthread_t producer_threads[PRODUCER_NUM], consumer_threads[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM], consumer_ids[CONSUMER_NUM];
for (int i = 0; i < PRODUCER_NUM; ++i) {
producer_ids[i] = i + 1;
pthread_create(&producer_threads[i], NULL, producer, &producer_ids[i]);
}
for (int i = 0; i < CONSUMER_NUM; ++i) {
consumer_ids[i] = i + 1;
pthread_create(&consumer_threads[i], NULL, consumer, &consumer_ids[i]);
}
for (int i = 0; i < PRODUCER_NUM; ++i) {
pthread_join(producer_threads[i], NULL);
}
for (int i = 0; i < CONSUMER_NUM; ++i) {
pthread_join(consumer_threads[i], NULL);
}
sem_destroy(&mutex);
sem_destroy(&empty);
sem_destroy(&full);
return 0;
}
```
该程序中,使用了三个信号量:`mutex`表示互斥信号量,`empty`表示空信号量,`full`表示满信号量。生产者和消费者进程(线程)都需要在临界区内对缓冲区进行操作,因此需要使用互斥信号量来保证互斥。生产者线程在往缓冲区中放入物品时,需要判断缓冲区是否已满,若已满则需要等待,因此需要使用空信号量;而消费者线程在从缓冲区中取出物品时,需要判断缓冲区是否为空,若为空则需要等待,因此需要使用满信号量。
在 `main` 函数中,首先使用 `sem_init` 函数对三个信号量进行初始化。然后创建多个生产者和消费者线程,并使用 `pthread_create` 函数启动线程。最后使用 `pthread_join` 函数等待所有线程结束,并使用 `sem_destroy` 函数销毁三个信号量。
在 `producer` 和 `consumer` 函数中,使用 `sem_wait` 函数和 `sem_post` 函数来对信号量进行操作,实现进程(线程)的同步与互斥。其中,`sem_wait` 函数会阻塞当前进程(线程),直到对应信号量的值不为0;而 `sem_post` 函数会增加对应信号量的值。
在 `producer` 函数中,首先随机生成一个物品,然后使用 `sem_wait` 函数等待缓冲区非满。当缓冲区非满时,使用 `sem_wait` 函数进入临界区,将物品放入缓冲区,并输出生产者编号和物品编号。最后使用 `sem_post` 函数退出临界区,并使用 `sem_post` 函数增加缓冲区元素个数。
在 `consumer` 函数中,首先使用 `sem_wait` 函数等待缓冲区非空。当缓冲区非空时,使用 `sem_wait` 函数进入临界区,从缓冲区取出物品,并输出消费者编号和物品编号。最后使用 `sem_post` 函数退出临界区,并使用 `sem_post` 函数减少缓冲区元素个数。
注意,本示例代码仅供参考,实际应用中需要根据具体情况进行相应的修改和调整。
阅读全文