Skip to content

Instantly share code, notes, and snippets.

@hanxi
Last active November 24, 2021 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hanxi/da13637b59d3bf7a243af1a1d525401b to your computer and use it in GitHub Desktop.
Save hanxi/da13637b59d3bf7a243af1a1d525401b to your computer and use it in GitHub Desktop.
哲学家进餐问题
// 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