山东大学操作系统实验吸烟者问题
时间: 2023-06-17 08:02:02 浏览: 176
吸烟者问题是一个经典的同步问题,它涉及到三个进程:一个代表桌子,另外两个代表吸烟者。
桌子进程负责往桌子上放烟草、纸和火柴。每个吸烟者进程需要烟草、纸和火柴中的两个才能抽烟。当一个吸烟者进程拥有了两个必需的材料之后,它将抽烟并通知桌子进程继续放置烟草、纸和火柴。
以下是一种可能的实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t table_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t match_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t paper_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t tobacco_cond = PTHREAD_COND_INITIALIZER;
int match_on_table = 0;
int paper_on_table = 0;
int tobacco_on_table = 0;
void *agent(void *arg) {
while (1) {
pthread_mutex_lock(&table_lock);
while (match_on_table && paper_on_table && tobacco_on_table) {
pthread_cond_wait(&match_cond, &table_lock);
pthread_cond_wait(&paper_cond, &table_lock);
pthread_cond_wait(&tobacco_cond, &table_lock);
}
int r = rand() % 3;
if (r == 0) {
match_on_table = 1;
printf("agent: put match on table\n");
pthread_cond_signal(&paper_cond);
pthread_cond_signal(&tobacco_cond);
} else if (r == 1) {
paper_on_table = 1;
printf("agent: put paper on table\n");
pthread_cond_signal(&match_cond);
pthread_cond_signal(&tobacco_cond);
} else {
tobacco_on_table = 1;
printf("agent: put tobacco on table\n");
pthread_cond_signal(&match_cond);
pthread_cond_signal(&paper_cond);
}
pthread_mutex_unlock(&table_lock);
sleep(1);
}
return NULL;
}
void *smoker_match(void *arg) {
while (1) {
pthread_mutex_lock(&table_lock);
while (!paper_on_table || !tobacco_on_table) {
pthread_cond_wait(&match_cond, &table_lock);
}
printf("smoker with match: start smoking\n");
match_on_table = 0;
paper_on_table = 0;
tobacco_on_table = 0;
pthread_mutex_unlock(&table_lock);
sleep(1);
}
return NULL;
}
void *smoker_paper(void *arg) {
while (1) {
pthread_mutex_lock(&table_lock);
while (!match_on_table || !tobacco_on_table) {
pthread_cond_wait(&paper_cond, &table_lock);
}
printf("smoker with paper: start smoking\n");
match_on_table = 0;
paper_on_table = 0;
tobacco_on_table = 0;
pthread_mutex_unlock(&table_lock);
sleep(1);
}
return NULL;
}
void *smoker_tobacco(void *arg) {
while (1) {
pthread_mutex_lock(&table_lock);
while (!match_on_table || !paper_on_table) {
pthread_cond_wait(&tobacco_cond, &table_lock);
}
printf("smoker with tobacco: start smoking\n");
match_on_table = 0;
paper_on_table = 0;
tobacco_on_table = 0;
pthread_mutex_unlock(&table_lock);
sleep(1);
}
return NULL;
}
int main() {
pthread_t agent_thread;
pthread_t smoker_match_thread;
pthread_t smoker_paper_thread;
pthread_t smoker_tobacco_thread;
pthread_create(&agent_thread, NULL, agent, NULL);
pthread_create(&smoker_match_thread, NULL, smoker_match, NULL);
pthread_create(&smoker_paper_thread, NULL, smoker_paper, NULL);
pthread_create(&smoker_tobacco_thread, NULL, smoker_tobacco, NULL);
pthread_join(agent_thread, NULL);
pthread_join(smoker_match_thread, NULL);
pthread_join(smoker_paper_thread, NULL);
pthread_join(smoker_tobacco_thread, NULL);
return 0;
}
```
在这个实现中,桌子进程负责放置材料,每个吸烟者进程会不断地等待桌子进程放置必需的材料。当桌子进程放置好两个必需的材料之后,对应的吸烟者进程会抽烟,并将桌子清空,通知桌子进程继续放置材料。这个实现使用了 pthread 库来实现线程同步。
阅读全文