Last active
November 24, 2021 06:05
-
-
Save hanxi/da13637b59d3bf7a243af1a1d525401b to your computer and use it in GitHub Desktop.
哲学家进餐问题
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gcc -std=c99 -g philosopher.c -o philosopher | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdbool.h> | |
struct philosopher { | |
int id; | |
int think_count; | |
bool eating; | |
struct philosopher *left; | |
struct philosopher *right; | |
pthread_mutex_t *pmutex; | |
pthread_cond_t cond; | |
pthread_t tid; | |
}; | |
void *think(void *arg) | |
{ | |
struct philosopher *pher = (struct philosopher *)arg; | |
pthread_mutex_t *pmutex = pher->pmutex; | |
pthread_mutex_lock(pmutex); | |
pher->eating = false; | |
pthread_cond_signal(&pher->left->cond); | |
pthread_cond_signal(&pher->right->cond); | |
pthread_mutex_unlock(pmutex); | |
(pher->think_count)++; | |
if (pher->think_count % 10 == 0) { | |
printf("philosopher %d has thought %d times.\n", pher->id, pher->think_count); | |
} | |
sleep(1); | |
} | |
void *eat(void *arg) | |
{ | |
struct philosopher *pher = (struct philosopher *)arg; | |
pthread_mutex_t *pmutex = pher->pmutex; | |
pthread_mutex_lock(pmutex); | |
while (pher->left->eating || pher->right->eating) { | |
pthread_cond_wait(&pher->cond, pmutex); | |
} | |
pher->eating = true; | |
pthread_mutex_unlock(pmutex); | |
sleep(1); | |
} | |
void *run(void *arg) | |
{ | |
struct philosopher *pher = (struct philosopher *)arg; | |
while (true) { | |
printf("run. id:%d\n", pher->id); | |
think(arg); | |
eat(arg); | |
} | |
return NULL; | |
} | |
int main() | |
{ | |
pthread_mutex_t mutex; | |
pthread_mutex_init(&mutex, NULL); | |
pthread_attr_t attr; | |
pthread_attr_init(&attr); | |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
struct philosopher phers[5]; | |
for (int i=0; i<5; i++) { | |
phers[i].id = i; | |
phers[i].think_count = 0; | |
phers[i].eating = false; | |
phers[i].left = &phers[(i+4)%5]; | |
phers[i].right = &phers[(i+1)%5]; | |
phers[i].pmutex = &mutex; | |
pthread_cond_init(&phers[i].cond, NULL); | |
pthread_create(&phers[i].tid, &attr, run, &phers[i]); | |
pthread_join(phers[i].tid, NULL); | |
} | |
while (true) { | |
sleep(1); | |
} | |
pthread_mutex_destroy(&mutex); | |
pthread_attr_destroy(&attr); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment