用c编程实现生产者-消费者进程的同步与互斥,题目要求: 1、至少支持两个生产者和两个消费者; 2、每次只能有一个生产者或消费者进入仓库; 3、仓库满时生产者不能进入仓库,仓库空时消费者不能进入仓库。 三、实验要求 1、至少使用一种调度算法实现进程调度过程;(10分,基础分5分,每增加一种调度算法增加2.5分) 2、模拟实现进程执行进度,而非调用一次生产者进程或消费者进程即执行完成,无法完整反映进程同步与互斥;(20分,按照设计并发效果酌情记分) 3、能够清晰反映执行状况,显示内容包括:进程基本状态、信号
时间: 2024-02-04 21:04:20 浏览: 68
生产者与消费者 进程的同步与互斥模拟
5星 · 资源好评率100%
以下是一个使用信号量来实现生产者-消费者进程同步与互斥的C程序示例,采用了先进先出(FIFO)调度算法:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX_NUM 10 // 仓库的最大容量
#define PRO_NUM 2 // 生产者的数量
#define CON_NUM 2 // 消费者的数量
// 仓库
int goods[MAX_NUM];
int front = 0; // 队首指针
int rear = 0; // 队尾指针
// 信号量
sem_t empty; // 空闲空间数
sem_t full; // 商品数
sem_t mutex; // 互斥访问仓库
// 生产者线程函数
void* producer(void* arg)
{
int id = *(int*)arg;
while(1)
{
// 等待空闲空间
sem_wait(&empty);
// 获取互斥访问仓库
sem_wait(&mutex);
// 如果仓库已满,等待
if((rear + 1) % MAX_NUM == front)
{
sem_post(&mutex);
sem_post(&empty);
continue;
}
// 生产商品并放入仓库
goods[rear] = 1;
rear = (rear + 1) % MAX_NUM;
printf("生产者%d生产了一个商品,当前仓库商品数量为%d\n", id, (rear - front + MAX_NUM) % MAX_NUM);
// 释放互斥访问仓库
sem_post(&mutex);
// 发送商品信号量
sem_post(&full);
}
return NULL;
}
// 消费者线程函数
void* consumer(void* arg)
{
int id = *(int*)arg;
while(1)
{
// 等待商品
sem_wait(&full);
// 获取互斥访问仓库
sem_wait(&mutex);
// 如果仓库为空,等待
if(front == rear)
{
sem_post(&mutex);
sem_post(&full);
continue;
}
// 从仓库中取出一个商品
int item = goods[front];
front = (front + 1) % MAX_NUM;
printf("消费者%d消费了一个商品,当前仓库商品数量为%d\n", id, (rear - front + MAX_NUM) % MAX_NUM);
// 释放互斥访问仓库
sem_post(&mutex);
// 发送空闲空间信号量
sem_post(&empty);
}
return NULL;
}
int main()
{
// 初始化信号量
sem_init(&empty, 0, MAX_NUM);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
// 创建生产者线程
pthread_t producer_tid[PRO_NUM];
int producer_id[PRO_NUM];
for(int i = 0; i < PRO_NUM; i++)
{
producer_id[i] = i + 1;
pthread_create(&producer_tid[i], NULL, producer, &producer_id[i]);
}
// 创建消费者线程
pthread_t consumer_tid[CON_NUM];
int consumer_id[CON_NUM];
for(int i = 0; i < CON_NUM; i++)
{
consumer_id[i] = i + 1;
pthread_create(&consumer_tid[i], NULL, consumer, &consumer_id[i]);
}
// 等待线程结束
for(int i = 0; i < PRO_NUM; i++)
pthread_join(producer_tid[i], NULL);
for(int i = 0; i < CON_NUM; i++)
pthread_join(consumer_tid[i], NULL);
// 销毁信号量
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
```
在这个示例中,我们使用了三个信号量来实现同步与互斥:`empty` 表示空闲空间数,`full` 表示商品数,`mutex` 表示互斥访问仓库。每个生产者线程在每次生产商品时,需要先等待空闲空间,然后获取互斥访问仓库并进行生产操作,最后释放互斥访问仓库并发送商品信号量。每个消费者线程在每次消费商品时,需要先等待商品,然后获取互斥访问仓库并进行消费操作,最后释放互斥访问仓库并发送空闲空间信号量。
在调度算法方面,我们使用了先进先出(FIFO)调度算法,即每个线程轮流执行,按照线程创建的先后顺序进行调度。可以看到,使用信号量来实现生产者-消费者进程同步与互斥比较简单,而且不易出现竞态条件等问题。
阅读全文