c语言实现:有一个师傅进程和三个学徒进程,每个学徒连续不断地组装产品,做一个产品需要A. B、C三种零件,这三个学徒分别掌握有A零件、B零件、C零件多个。 要求完成以下功能: (1)师傅源源不断地供应上述三种零件,但他每次只将其中的两种零件放在桌子上(所 放零件由rand%3函数生成的0-2之间的随机数决定)。 (2)具有另一零件的学徒就可以组装产品,且做完后给师傅发信号,然后师傅再拿出 两种零件放在桌上。 3)每次只能有一个进程放入或取出零件。 (4)利用同步与互斥的相关知识编写仿真系统实现以上过程,要能够清晰表达产品生 产的全过程。
时间: 2024-01-21 13:19:30 浏览: 93
以下是使用信号量实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define N 3 // 零件种类数
#define M 2 // 师傅每次放的零件种类数
#define K 3 // 学徒数目
sem_t sem[N]; // 各种零件的信号量
sem_t mutex; // 互斥信号量,控制桌子的访问
int parts[M]; // 桌子上的零件
int count[M] = {0}; // 桌子上各种零件的数量
int finished = 0; // 完成组装的产品数量
void* master(void* arg) {
while (finished < 10) { // 组装10个产品
int type1 = rand() % N;
int type2 = rand() % N;
while (type1 == type2) { // 保证放的两种零件不同
type2 = rand() % N;
}
sem_wait(&mutex); // 互斥访问桌子
parts[0] = type1;
parts[1] = type2;
count[type1]++;
count[type2]++;
printf("Master puts %c and %c on the table.\n", 'A' + type1, 'A' + type2);
sem_post(&sem[type1]); // 放入零件1
sem_post(&sem[type2]); // 放入零件2
sem_post(&mutex); // 释放桌子
sleep(1); // 休息一段时间
}
printf("Master has finished his work.\n");
pthread_exit(NULL);
}
void* apprentice(void* arg) {
int type = *(int*)arg; // 学徒掌握的零件种类
while (finished < 10) { // 组装10个产品
sem_wait(&sem[type]); // 等待有自己掌握的零件
sem_wait(&mutex); // 互斥访问桌子
count[type]--;
for (int i = 0; i < M; i++) {
if (parts[i] == type) {
parts[i] = -1; // 取走零件
break;
}
}
printf("Apprentice %d takes a %c from the table.\n", type, 'A' + type);
// 检查是否有另一种零件
int type1 = -1;
int type2 = -1;
for (int i = 0; i < M; i++) {
if (parts[i] != -1 && type1 == -1) {
type1 = parts[i];
} else if (parts[i] != -1 && type2 == -1) {
type2 = parts[i];
}
}
if (type1 != -1 && type2 != -1) { // 另一种零件也有了,可以组装
parts[0] = -1;
parts[1] = -1;
printf("Apprentice %d assembles a product.\n", type);
finished++;
}
sem_post(&mutex); // 释放桌子
}
printf("Apprentice %d has finished his work.\n", type);
pthread_exit(NULL);
}
int main() {
pthread_t threads[K+1];
sem_init(&mutex, 0, 1); // 初始化互斥信号量为1
for (int i = 0; i < N; i++) {
sem_init(&sem[i], 0, 0); // 初始化各种零件的信号量为0
}
pthread_create(&threads[0], NULL, master, NULL); // 创建师傅线程
for (int i = 1; i <= K; i++) {
pthread_create(&threads[i], NULL, apprentice, (void*)&(i-1)); // 创建学徒线程
}
for (int i = 0; i <= K; i++) {
pthread_join(threads[i], NULL); // 等待所有线程结束
}
for (int i = 0; i < N; i++) {
sem_destroy(&sem[i]); // 销毁各种零件的信号量
}
sem_destroy(&mutex); // 销毁互斥信号量
return 0;
}
```
每个学徒线程的参数是一个指向int的指针,这个int表示学徒掌握的零件类型(0表示A,1表示B,2表示C)。师傅线程不需要参数。
程序通过信号量控制各进程的访问,保证了同步与互斥。程序输出的内容可以清晰地表达产品生产的全过程。运行结果示意图如下:
```
Master puts A and B on the table.
Apprentice 2 takes a C from the table.
Apprentice 0 takes a A from the table.
Apprentice 1 takes a B from the table.
Apprentice 0 assembles a product.
Master puts B and C on the table.
Apprentice 2 takes a A from the table.
Apprentice 1 takes a C from the table.
Apprentice 2 assembles a product.
Master puts A and C on the table.
Apprentice 0 takes a B from the table.
Apprentice 1 takes a A from the table.
Apprentice 1 assembles a product.
Master puts B and A on the table.
Apprentice 0 takes a C from the table.
Apprentice 2 takes a B from the table.
Apprentice 0 assembles a product.
Master puts C and B on the table.
Apprentice 2 takes a A from the table.
Apprentice 0 takes a B from the table.
Apprentice 2 assembles a product.
Master puts A and C on the table.
Apprentice 1 takes a B from the table.
Apprentice 0 takes a C from the table.
Apprentice 1 assembles a product.
Master puts B and C on the table.
Apprentice 2 takes a A from the table.
Apprentice 1 takes a C from the table.
Apprentice 2 assembles a product.
Master puts A and C on the table.
Apprentice 0 takes a B from the table.
Apprentice 1 takes a A from the table.
Apprentice 0 assembles a product.
Master has finished his work.
Apprentice 1 has finished his work.
Apprentice 2 has finished his work.
Apprentice 0 has finished his work.
```
阅读全文