|
|
#include <stdio.h> #include <thread.h> #include <synch.h> #define NPHIL 5 static sema_t forks[NPHIL]; typedef struct { int id, left_fork, right_fork; } philo_t; static philo_t philo_args[NPHIL]; static void *philo(void*); extern void *sometask(void*); main() { int i; for(i = 0; i < NPHIL; i++){ (void)sema_init(&forks[i], 1, USYNC_THREAD, NULL); philo_args[i].id = i; philo_args[i].left_fork = i; philo_args[i].rght_fork = (i+1)%NPHIL; } for(i = 0; i < NPHIL; i++) (void)thr_create(NULL, 0, philo, &philo_args[i], 0, NULL); thr_exit(NULL); /*NOTREACHED*/ } static void *philo(void *philo_arg) { philo_t *argp = (philo_t *)philo_arg; int id = argp->id; int left = argp->left_fork; int rght = argp->rght_fork; (void)printf("thrID %ld id %d left %d rght %d\n", thr_self(), id, left, rght); for(;;){ (void)sema_wait(&forks[left]); (void)sema_wait(&forks[rght]); (void)printf("philo %d eating w. %d and %d\n", id, left, rght); (void)sometask(NULL); /* eating */ (void)printf("philo %d done w. %d and %d\n", id, left, rght); (void)sema_post(&forks[left]); (void)sema_post(&forks[rght]); (void)sometask(NULL); /* think */ } /* NOTREACHED */ }
Dining philosophers
The program in ``Dining philosophers'' shows an implementation of the classic ``dining philosophers'' problem using the facilities of the Threads Library.
In this problem there are N philosophers sitting at a round table eating and thinking. Each has a plate of spaghetti and there is a single fork (a total of N forks) between each pair. Each philosopher must use two forks to eat the spaghetti. Each philosopher puts down both forks to think. This simple problem illustrates many of the issues in concurrent programming, such as the need for synchronization to prevent deadlock. The philosophers represent processes that require shared resources (the forks).
Some features of this program are: