C语言: 有一个师傅进程和三个学徒进程,每个学徒连续不断地组装产品,做一个产品需要A、B、C三种零件,这三个学徒分别掌握有A零件、B零件、C零件多个。 要求完成以下功能: (1)师傅源源不断地供应上述三种零件,但他每次只将其中的两种零件放在桌子上(所放零件由rand % 3函数生成的0-2之间的随机数决定)。 (2)具有另一零件的学徒就可以组装产品,且做完后给师傅发信号,然后师傅再拿出两种零件放在桌上。 (3)每次只能有一个进程放入或取出零件。
时间: 2024-02-16 16:05:06 浏览: 169
这是一个经典的生产者消费者问题,可以使用信号量实现。以下是 C 语言的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define N 3 // 零件种类数
#define M 2 // 每次放置的零件数
#define K 10 // 最多可组装的产品数
int parts[N] = {0}; // 零件库存
sem_t sems[N]; // 信号量数组
sem_t mutex; // 互斥信号量
int count = 0; // 已组装的产品数量
void* master(void* arg)
{
int i, j;
while (count < K) {
// 随机选择两种零件放在桌子上
i = rand() % N;
j = rand() % N;
while (i == j) j = rand() % N;
sem_wait(&mutex);
parts[i]++; parts[j]++; // 放置零件
printf("Master puts parts %d and %d on the table.\n", i, j);
sem_post(&mutex);
// 等待学徒取走零件
sem_wait(&sems[i]);
sem_wait(&sems[j]);
}
return NULL;
}
void* apprentice(void* arg)
{
int id = *(int*)arg;
int i, j;
while (count < K) {
// 随机选择一种不同于自己掌握的零件
i = id; j = (id + 1) % N;
while (i == id || j == id) {
i = rand() % N;
j = rand() % N;
}
sem_wait(&mutex);
if (parts[i] > 0 && parts[j] > 0) {
parts[i]--; parts[j]--; // 取走零件
printf("Apprentice %d takes parts %d and %d from the table.\n", id, i, j);
sem_post(&sems[i]);
sem_post(&sems[j]);
count++; // 组装产品
}
sem_post(&mutex);
}
return NULL;
}
int main()
{
int i, id[N];
pthread_t tid[N+1];
// 初始化信号量
sem_init(&mutex, 0, 1);
for (i = 0; i < N; i++) {
sem_init(&sems[i], 0, 0);
}
// 创建线程
for (i = 0; i < N; i++) {
id[i] = i;
pthread_create(&tid[i], NULL, apprentice, &id[i]);
}
pthread_create(&tid[N], NULL, master, NULL);
// 等待线程结束
for (i = 0; i <= N; i++) {
pthread_join(tid[i], NULL);
}
// 销毁信号量
sem_destroy(&mutex);
for (i = 0; i < N; i++) {
sem_destroy(&sems[i]);
}
return 0;
}
```
在该程序中,师傅和学徒分别对应两个线程函数 master 和 apprentice。师傅使用 rand 函数随机选择两种零件放在桌子上,并使用信号量 mutex 进行互斥保护。学徒使用 while 循环等待有零件可以取走,并使用信号量 sems 进行同步。每当学徒取走两种零件后,就会使用 sem_post 函数通知师傅可以放置新的零件了。组装产品的数量 count 也需要进行互斥保护。
注意:该代码只是一个示例,实际应用中需要根据具体情况进行修改和调整。
阅读全文