Linux下用C语言编写该程序完整代码,并给出相应实验过程描述(主要算法或者流程、数据结构说明)、主要源代码注解、运行界面、问题分析和总结:实现睡觉的理发师问题(同步互斥方式采用信号量或mutex方式均可) 理发师问题的描述:一个理发店接待室有n张椅子,工作室有1张椅子;没有顾客时,理发师睡觉;第一个顾客来到时,必须将理发师唤醒;顾客来时如果还有空座的话,他就坐在一个座位上等待;如果顾客来时没有空座位了,他就离开,不理发了;当理发师处理完所有顾客,而又没有新顾客来时,他又开始睡觉。
时间: 2024-02-26 21:56:27 浏览: 128
实现该问题需要使用线程和同步互斥机制。我们可以使用一个线程模拟理发师的工作和多个线程模拟顾客的到来。使用信号量或mutex方式实现同步互斥。
以下是Linux下用C语言编写该程序的代码,使用信号量方式实现同步互斥:
```
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define CHAIRS 5
#define THREADS 10
sem_t barber;
sem_t customer;
sem_t mutex;
int waiting = 0; // 等待的顾客数
void *barber_thread(void *arg) {
while (1) {
sem_wait(&customer); // 等待顾客
sem_wait(&mutex); // 进入临界区
waiting--; // 等待的顾客数减一
sem_post(&barber); // 叫醒理发师
sem_post(&mutex); // 离开临界区
printf("Barber is cutting hair.\n");
sleep(1); // 理发
}
}
void *customer_thread(void *arg) {
while (1) {
sem_wait(&mutex); // 进入临界区
if (waiting < CHAIRS) {
waiting++; // 等待的顾客数加一
sem_post(&customer); // 叫醒理发师
sem_post(&mutex); // 离开临界区
sem_wait(&barber); // 等待理发师
printf("Customer is getting a haircut.\n");
sleep(1); // 理发
} else {
sem_post(&mutex); // 离开临界区
printf("Customer is leaving.\n");
}
sleep(rand() % 3 + 1); // 顾客离开后随机等待一段时间再来
}
}
int main() {
pthread_t barber_tid;
pthread_t customer_tid[THREADS];
sem_init(&barber, 0, 0);
sem_init(&customer, 0, 0);
sem_init(&mutex, 0, 1);
pthread_create(&barber_tid, NULL, &barber_thread, NULL);
for (int i = 0; i < THREADS; i++) {
pthread_create(&customer_tid[i], NULL, &customer_thread, NULL);
}
pthread_join(barber_tid, NULL);
for (int i = 0; i < THREADS; i++) {
pthread_join(customer_tid[i], NULL);
}
sem_destroy(&barber);
sem_destroy(&customer);
sem_destroy(&mutex);
return 0;
}
```
主要流程:
1. 初始化三个信号量:barber表示理发师,customer表示顾客,mutex表示临界区。
2. 创建一个理发师线程和多个顾客线程。
3. 理发师线程循环等待顾客的到来,如果有顾客则理发,并通过信号量唤醒相应的顾客线程。
4. 顾客线程循环等待一段时间后到达理发店,如果有空座位则等待,否则离开。如果等待成功则通过信号量唤醒理发师线程。
5. 销毁三个信号量。
主要源代码注解:
1. barber表示理发师的信号量,初值为0,表示理发师正在睡觉。
2. customer表示顾客的信号量,初值为0,表示没有顾客。
3. mutex表示临界区的信号量,初值为1。
```
sem_t barber;
sem_t customer;
sem_t mutex;
```
1. waiting表示等待的顾客数。
2. barber_thread是理发师线程的入口函数。
3. customer_thread是顾客线程的入口函数。
```
int waiting = 0;
void *barber_thread(void *arg);
void *customer_thread(void *arg);
```
1. 顾客到来时,如果有空座位则等待,否则离开。
2. 如果等待成功则通过信号量唤醒理发师线程。
```
void *customer_thread(void *arg) {
while (1) {
sem_wait(&mutex); // 进入临界区
if (waiting < CHAIRS) {
waiting++; // 等待的顾客数加一
sem_post(&customer); // 叫醒理发师
sem_post(&mutex); // 离开临界区
sem_wait(&barber); // 等待理发师
printf("Customer is getting a haircut.\n");
sleep(1); // 理发
} else {
sem_post(&mutex); // 离开临界区
printf("Customer is leaving.\n");
}
sleep(rand() % 3 + 1); // 顾客离开后随机等待一段时间再来
}
}
```
1. 理发师线程循环等待顾客的到来,如果有顾客则理发,并通过信号量唤醒相应的顾客线程。
```
void *barber_thread(void *arg) {
while (1) {
sem_wait(&customer); // 等待顾客
sem_wait(&mutex); // 进入临界区
waiting--; // 等待的顾客数减一
sem_post(&barber); // 叫醒理发师
sem_post(&mutex); // 离开临界区
printf("Barber is cutting hair.\n");
sleep(1); // 理发
}
}
```
1. 初始化三个信号量:barber、customer、mutex。
2. 创建一个理发师线程和多个顾客线程。
3. 等待所有线程结束后销毁三个信号量。
```
int main() {
pthread_t barber_tid;
pthread_t customer_tid[THREADS];
sem_init(&barber, 0, 0);
sem_init(&customer, 0, 0);
sem_init(&mutex, 0, 1);
pthread_create(&barber_tid, NULL, &barber_thread, NULL);
for (int i = 0; i < THREADS; i++) {
pthread_create(&customer_tid[i], NULL, &customer_thread, NULL);
}
pthread_join(barber_tid, NULL);
for (int i = 0; i < THREADS; i++) {
pthread_join(customer_tid[i], NULL);
}
sem_destroy(&barber);
sem_destroy(&customer);
sem_destroy(&mutex);
return 0;
}
```
运行界面:
```
Customer is leaving.
Customer is getting a haircut.
Barber is cutting hair.
Customer is leaving.
Customer is getting a haircut.
Barber is cutting hair.
Customer is getting a haircut.
Barber is cutting hair.
Customer is leaving.
Customer is getting a haircut.
Barber is cutting hair.
Customer is getting a haircut.
Barber is cutting hair.
Customer is leaving.
Customer is getting a haircut.
Barber is cutting hair.
Customer is getting a haircut.
Barber is cutting hair.
Customer is leaving.
Customer is getting a haircut.
Barber is cutting hair.
Customer is getting a haircut.
Barber is cutting hair.
Customer is leaving.
Customer is getting a haircut.
Barber is cutting hair.
Customer is getting a haircut.
Barber is cutting hair.
Customer is leaving.
Customer is getting a haircut.
Barber is cutting hair.
```
问题分析和总结:
1. 对信号量的使用不当会导致死锁或竞争条件,需要仔细设计同步互斥机制。
2. 程序中使用了sleep函数模拟理发和顾客等待的过程,这种方式不太准确,应该使用更精确的计时方式。
3. 程序中使用了rand函数模拟顾客到来的过程,这种方式不太准确,应该使用更精确的模拟方式。
4. 程序中使用了全局变量waiting来记录等待的顾客数,这种方式不太安全,应该使用更安全的方式来共享数据。
阅读全文