#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define N 5
#define THINKING 0
#define HUNGRY 1
#define EATING 2
int state[N];
sem_t mutex;
sem_t S[N];
void test(int i)
{
if (state[i] == HUNGRY &&
state[(i + 4) % N] != EATING &&
state[(i + 1) % N] != EATING)
{
state[i] = EATING;
printf("Philosopher %d takes forks and starts eating\n", i);
sem_post(&S[i]);
}
}
void take_forks(int i)
{
sem_wait(&mutex);
state[i] = HUNGRY;
printf("Philosopher %d is HUNGRY\n", i);
test(i);
sem_post(&mutex);
sem_wait(&S[i]);
}
void put_forks(int i)
{
sem_wait(&mutex);
state[i] = THINKING;
printf("Philosopher %d puts down forks and starts THINKING\n", i);
test((i + 4) % N);
test((i + 1) % N);
sem_post(&mutex);
}
void *philosopher(void *num)
{
int i = *(int *)num;
for (int j = 0; j < 2; j++)
{
printf("Philosopher %d is THINKING\n", i);
sleep(1);
take_forks(i);
sleep(1);
printf("Philosopher %d finishes eating\n", i);
put_forks(i);
}
return NULL;
}
int main()
{
pthread_t thread[N];
int id[N];
sem_init(&mutex, 0, 1);
for (int i = 0; i < N; i++)
{
state[i] = THINKING;
sem_init(&S[i], 0, 0);
}
for (int i = 0; i < N; i++)
{
id[i] = i;
pthread_create(&thread[i], NULL, philosopher, &id[i]);
}
for (int i = 0; i < N; i++)
{
pthread_join(thread[i], NULL);
}
sem_destroy(&mutex);
for (int i = 0; i < N; i++)
sem_destroy(&S[i]);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxwdGhyZWFkLmg+CiNpbmNsdWRlIDxzZW1hcGhvcmUuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojZGVmaW5lIE4gNQojZGVmaW5lIFRISU5LSU5HIDAKI2RlZmluZSBIVU5HUlkgMQojZGVmaW5lIEVBVElORyAyCmludCBzdGF0ZVtOXTsKc2VtX3QgbXV0ZXg7CnNlbV90IFNbTl07CnZvaWQgdGVzdChpbnQgaSkKewogICAgaWYgKHN0YXRlW2ldID09IEhVTkdSWSAmJgogICAgICAgIHN0YXRlWyhpICsgNCkgJSBOXSAhPSBFQVRJTkcgJiYKICAgICAgICBzdGF0ZVsoaSArIDEpICUgTl0gIT0gRUFUSU5HKQogICAgewogICAgICAgIHN0YXRlW2ldID0gRUFUSU5HOwogICAgICAgIHByaW50ZigiUGhpbG9zb3BoZXIgJWQgdGFrZXMgZm9ya3MgYW5kIHN0YXJ0cyBlYXRpbmdcbiIsIGkpOwogICAgICAgIHNlbV9wb3N0KCZTW2ldKTsKICAgIH0KfQp2b2lkIHRha2VfZm9ya3MoaW50IGkpCnsKc2VtX3dhaXQoJm11dGV4KTsKIHN0YXRlW2ldID0gSFVOR1JZOwogICAgcHJpbnRmKCJQaGlsb3NvcGhlciAlZCBpcyBIVU5HUllcbiIsIGkpOwogdGVzdChpKTsKIHNlbV9wb3N0KCZtdXRleCk7CiAgICBzZW1fd2FpdCgmU1tpXSk7Cn0Kdm9pZCBwdXRfZm9ya3MoaW50IGkpCnsKICAgIHNlbV93YWl0KCZtdXRleCk7CiBzdGF0ZVtpXSA9IFRISU5LSU5HOwogICAgcHJpbnRmKCJQaGlsb3NvcGhlciAlZCBwdXRzIGRvd24gZm9ya3MgYW5kIHN0YXJ0cyBUSElOS0lOR1xuIiwgaSk7CiB0ZXN0KChpICsgNCkgJSBOKTsKICAgIHRlc3QoKGkgKyAxKSAlIE4pOwpzZW1fcG9zdCgmbXV0ZXgpOwp9CnZvaWQgKnBoaWxvc29waGVyKHZvaWQgKm51bSkKewogICAgaW50IGkgPSAqKGludCAqKW51bTsKIGZvciAoaW50IGogPSAwOyBqIDwgMjsgaisrKQogICAgewogICAgICAgIHByaW50ZigiUGhpbG9zb3BoZXIgJWQgaXMgVEhJTktJTkdcbiIsIGkpOwogICAgICAgIHNsZWVwKDEpOwogdGFrZV9mb3JrcyhpKTsKICBzbGVlcCgxKTsKcHJpbnRmKCJQaGlsb3NvcGhlciAlZCBmaW5pc2hlcyBlYXRpbmdcbiIsIGkpOwogIHB1dF9mb3JrcyhpKTsKICAgIH0KICAgcmV0dXJuIE5VTEw7Cn0KaW50IG1haW4oKQp7CiAgICBwdGhyZWFkX3QgdGhyZWFkW05dOwogICAgaW50IGlkW05dOwpzZW1faW5pdCgmbXV0ZXgsIDAsIDEpOwpmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykKICAgIHsKICAgICAgICBzdGF0ZVtpXSA9IFRISU5LSU5HOwogICAgICAgIHNlbV9pbml0KCZTW2ldLCAwLCAwKTsKICAgIH0KICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykKICAgIHsKICAgICAgICBpZFtpXSA9IGk7CiAgICAgICAgcHRocmVhZF9jcmVhdGUoJnRocmVhZFtpXSwgTlVMTCwgcGhpbG9zb3BoZXIsICZpZFtpXSk7CiAgICB9CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICB7CiAgICAgICAgcHRocmVhZF9qb2luKHRocmVhZFtpXSwgTlVMTCk7CiAgICB9CiBzZW1fZGVzdHJveSgmbXV0ZXgpOwogZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICAgICAgc2VtX2Rlc3Ryb3koJlNbaV0pOwogcmV0dXJuIDA7Cn0K