Skip to content

Instantly share code, notes, and snippets.

@andersonfraga
Last active April 25, 2017 00:38
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 andersonfraga/0eb0773c23c0c15861cb62da8ca03249 to your computer and use it in GitHub Desktop.
Save andersonfraga/0eb0773c23c0c15861cb62da8ca03249 to your computer and use it in GitHub Desktop.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NANO_SECOND_MULTIPLIER 1000000
typedef struct philosopher_sct {
int think;
int waited;
int consume;
pthread_t person;
pthread_mutex_t *spoon_l, *spoon_r;
} Philosopher;
volatile int running = 1;
void *service(void *p);
int main(int argc, char const *argv[])
{
int num_phil, seconds;
if (argc < 3) {
printf("Usage: %s num_phil seconds \n", argv[0]);
return 0;
}
if (sscanf(argv[1], "%i", &num_phil) != 1) {
fprintf(stderr, "Error: <num_phil> needs be int\n");
return 0;
}
if (sscanf(argv[2], "%i", &seconds) != 1) {
fprintf(stderr, "Error: <seconds> needs be int\n");
return 0;
}
printf("%d filósofos em %d segundos...\n", num_phil, seconds);
srand(time(NULL));
pthread_mutex_t forks[num_phil];
Philosopher philosophers[num_phil];
Philosopher *phil;
for (int i = 0; i < num_phil; i++) {
pthread_mutex_init(&forks[i], NULL);
}
for (int i = 0; i < num_phil; i++) {
phil = &philosophers[i];
phil->think = 0;
phil->waited = 0;
phil->consume = 0;
phil->spoon_l = &forks[i];
phil->spoon_r = &forks[(i+1) % num_phil];
pthread_create(&phil->person, NULL, (void *) service, (void *) phil);
}
sleep(seconds);
running = 0;
for (int i = 0; i < num_phil; i++) {
phil = &philosophers[i];
pthread_join(phil->person, NULL);
}
// report
printf("\t#\t| think\t| waited\t| consume\n");
for (int i = 0; i < num_phil; i++) {
phil = &philosophers[i];
printf("\t%d\t|\t%d\t|\t%d\t|\t%d\n", i, phil->think, phil->waited, phil->consume);
}
return 0;
}
void *service(void *data)
{
Philosopher *person = (Philosopher*) data;
int failed;
sleep(5);
person->think++;
while (running) {
failed = pthread_mutex_trylock(person->spoon_l);
if (failed == 0) {
person->waited++;
sleep(rand() % 3);
continue;
}
failed = pthread_mutex_trylock(person->spoon_r);
if (failed == 0) {
pthread_mutex_unlock(person->spoon_l);
person->waited++;
sleep(rand() % 3);
continue;
}
// usleep deprecated...
nanosleep((const struct timespec[]){
{0, 2 * NANO_SECOND_MULTIPLIER}
}, NULL);
person->consume++;
pthread_mutex_unlock(person->spoon_r);
pthread_mutex_unlock(person->spoon_l);
person->think++;
sleep(5);
}
return NULL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment