Requisito previo: sincronización de procesos , semáforos , cena-filósofos Solución usando monitores
El problema del filósofo cenador: el problema del filósofo cenador establece que los filósofos K se sientan alrededor de una mesa circular con un palillo entre cada par de filósofos. Hay un palillo entre cada filósofo. Un filósofo puede comer si puede recoger los dos palillos adyacentes a él. Un palillo puede ser recogido por cualquiera de sus seguidores adyacentes, pero no por ambos.
Solución de semáforo para cenar filósofo:
cada filósofo está representado por el siguiente pseudocódigo:
process P[i] while true do { THINK; PICKUP(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]); EAT; PUTDOWN(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]) }
Hay tres estados del filósofo: PENSAMIENTO, HAMBRE y COMER . Aquí hay dos semáforos: Mutex y una array de semáforos para los filósofos. Mutex se usa de tal manera que dos filósofos no pueden acceder al retiro o al retiro al mismo tiempo. La array se utiliza para controlar el comportamiento de cada filósofo. Sin embargo, los semáforos pueden resultar en interbloqueos debido a errores de programación.
Código –
C
#include <pthread.h> #include <semaphore.h> #include <stdio.h> #define N 5 #define THINKING 2 #define HUNGRY 1 #define EATING 0 #define LEFT (phnum + 4) % N #define RIGHT (phnum + 1) % N int state[N]; int phil[N] = { 0, 1, 2, 3, 4 }; sem_t mutex; sem_t S[N]; void test(int phnum) { if (state[phnum] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) { // state that eating state[phnum] = EATING; sleep(2); printf("Philosopher %d takes fork %d and %d\n", phnum + 1, LEFT + 1, phnum + 1); printf("Philosopher %d is Eating\n", phnum + 1); // sem_post(&S[phnum]) has no effect // during takefork // used to wake up hungry philosophers // during putfork sem_post(&S[phnum]); } } // take up chopsticks void take_fork(int phnum) { sem_wait(&mutex); // state that hungry state[phnum] = HUNGRY; printf("Philosopher %d is Hungry\n", phnum + 1); // eat if neighbours are not eating test(phnum); sem_post(&mutex); // if unable to eat wait to be signalled sem_wait(&S[phnum]); sleep(1); } // put down chopsticks void put_fork(int phnum) { sem_wait(&mutex); // state that thinking state[phnum] = THINKING; printf("Philosopher %d putting fork %d and %d down\n", phnum + 1, LEFT + 1, phnum + 1); printf("Philosopher %d is thinking\n", phnum + 1); test(LEFT); test(RIGHT); sem_post(&mutex); } void* philosopher(void* num) { while (1) { int* i = num; sleep(1); take_fork(*i); sleep(0); put_fork(*i); } } int main() { int i; pthread_t thread_id[N]; // initialize the semaphores sem_init(&mutex, 0, 1); for (i = 0; i < N; i++) sem_init(&S[i], 0, 0); for (i = 0; i < N; i++) { // create philosopher processes pthread_create(&thread_id[i], NULL, philosopher, &phil[i]); printf("Philosopher %d is thinking\n", i + 1); } for (i = 0; i < N; i++) pthread_join(thread_id[i], NULL); }
Nota: el siguiente programa puede compilarse solo con compiladores C con semáforo y biblioteca pthread.
Referencias –
Solución de los filósofos gastronómicos – cs.gordon.edu
Solución de los filósofos gastronómicos – cs.indiana.edu
Publicación traducida automáticamente
Artículo escrito por Subham Biswas y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA