#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;
}
CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8cHRocmVhZC5oPgojaW5jbHVkZSA8c2VtYXBob3JlLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2RlZmluZSBOIDUKI2RlZmluZSBUSElOS0lORyAwCiNkZWZpbmUgSFVOR1JZIDEKI2RlZmluZSBFQVRJTkcgMgppbnQgc3RhdGVbTl07CnNlbV90IG11dGV4OwpzZW1fdCBTW05dOwp2b2lkIHRlc3QoaW50IGkpCnsKICAgIGlmIChzdGF0ZVtpXSA9PSBIVU5HUlkgJiYKICAgICAgICBzdGF0ZVsoaSArIDQpICUgTl0gIT0gRUFUSU5HICYmCiAgICAgICAgc3RhdGVbKGkgKyAxKSAlIE5dICE9IEVBVElORykKICAgIHsKICAgICAgICBzdGF0ZVtpXSA9IEVBVElORzsKICAgICAgICBwcmludGYoIlBoaWxvc29waGVyICVkIHRha2VzIGZvcmtzIGFuZCBzdGFydHMgZWF0aW5nXG4iLCBpKTsKICAgICAgICBzZW1fcG9zdCgmU1tpXSk7CiAgICB9Cn0Kdm9pZCB0YWtlX2ZvcmtzKGludCBpKQp7CnNlbV93YWl0KCZtdXRleCk7CiBzdGF0ZVtpXSA9IEhVTkdSWTsKICAgIHByaW50ZigiUGhpbG9zb3BoZXIgJWQgaXMgSFVOR1JZXG4iLCBpKTsKIHRlc3QoaSk7CiBzZW1fcG9zdCgmbXV0ZXgpOwogICAgc2VtX3dhaXQoJlNbaV0pOwp9CnZvaWQgcHV0X2ZvcmtzKGludCBpKQp7CiAgICBzZW1fd2FpdCgmbXV0ZXgpOwogc3RhdGVbaV0gPSBUSElOS0lORzsKICAgIHByaW50ZigiUGhpbG9zb3BoZXIgJWQgcHV0cyBkb3duIGZvcmtzIGFuZCBzdGFydHMgVEhJTktJTkdcbiIsIGkpOwogdGVzdCgoaSArIDQpICUgTik7CiAgICB0ZXN0KChpICsgMSkgJSBOKTsKc2VtX3Bvc3QoJm11dGV4KTsKfQp2b2lkICpwaGlsb3NvcGhlcih2b2lkICpudW0pCnsKICAgIGludCBpID0gKihpbnQgKiludW07CiBmb3IgKGludCBqID0gMDsgaiA8IDI7IGorKykKICAgIHsKICAgICAgICBwcmludGYoIlBoaWxvc29waGVyICVkIGlzIFRISU5LSU5HXG4iLCBpKTsKICAgICAgICBzbGVlcCgxKTsKIHRha2VfZm9ya3MoaSk7CiAgc2xlZXAoMSk7CnByaW50ZigiUGhpbG9zb3BoZXIgJWQgZmluaXNoZXMgZWF0aW5nXG4iLCBpKTsKICBwdXRfZm9ya3MoaSk7CiAgICB9CiAgIHJldHVybiBOVUxMOwp9CmludCBtYWluKCkKewogICAgcHRocmVhZF90IHRocmVhZFtOXTsKICAgIGludCBpZFtOXTsKc2VtX2luaXQoJm11dGV4LCAwLCAxKTsKZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICB7CiAgICAgICAgc3RhdGVbaV0gPSBUSElOS0lORzsKICAgICAgICBzZW1faW5pdCgmU1tpXSwgMCwgMCk7CiAgICB9CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICB7CiAgICAgICAgaWRbaV0gPSBpOwogICAgICAgIHB0aHJlYWRfY3JlYXRlKCZ0aHJlYWRbaV0sIE5VTEwsIHBoaWxvc29waGVyLCAmaWRbaV0pOwogICAgfQogIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKQogICAgewogICAgICAgIHB0aHJlYWRfam9pbih0aHJlYWRbaV0sIE5VTEwpOwogICAgfQogc2VtX2Rlc3Ryb3koJm11dGV4KTsKIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKQogICAgICAgIHNlbV9kZXN0cm95KCZTW2ldKTsKIHJldHVybiAwOwp9CgoK