The Dining Philosophers Problem is a classic concurrency problem in computer science. This code provides an alternative implementation of the problem using pthreads in C.
- One or more philosophers sit at a round table.
- The philosophers alternatively eat, think, or sleep.
- There are forks on the table, one for each philosopher.
- Each philosopher takes their left and right forks to eat.
- When a philosopher finishes eating, they put their forks back on the table and start sleeping.
- You have to write two programs:
philo
andphilo_bonus
(for the bonus part). - Global variables are forbidden.
- The programs should take the following arguments:
number_of_philosophers
: The number of philosophers and forks.time_to_die
: If a philosopher doesn't start eating within this time, they die.time_to_eat
: The time it takes for a philosopher to eat.time_to_sleep
: The time a philosopher spends sleeping.[number_of_times_each_philosopher_must_eat]
: Optional argument to stop the simulation after all philosophers have eaten a certain number of times.
- Each philosopher is a thread.
- There is one fork between each pair of philosophers.
- Protect the forks' state with a mutex.
- All the forks are put in the middle of the table, represented by a semaphore.
- Each philosopher is a process.
- The main process is not a philosopher.
- All state changes of a philosopher should be formatted as follows:
{timestamp} {philosopher_number} has taken a fork
{timestamp} {philosopher_number} is eating
{timestamp} {philosopher_number} is sleeping
{timestamp} {philosopher_number} is thinking
{timestamp} {philosopher_number} died
- Timestamps are in milliseconds.
The programs should comply with the specified requirements. Some of the external functions that can be used are:
- memset, printf, malloc, free, write, ft_usleep
- gettimeofday, pthread_create, pthread_detach, pthread_join
- pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_lock, pthread_mutex_unlock
- fork, kill, exit, waitpid, sem_open, sem_close, sem_post, sem_wait, sem_unlink
#include <string.h>
int main() {
char arr[10];
memset(arr, 'A', 10); // Fill the array with 'A' 10 times
return 0;
}
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
#include <stdlib.h>
int main() {
int *ptr = (int *)malloc(10 * sizeof(int)); // Allocate memory for 10 integers
// Use the allocated memory
free(ptr); // Free the allocated memory when done using it
return 0;
}
#include <unistd.h>
int main() {
char buffer[] = "Hello, World!\n";
write(STDOUT_FILENO, buffer, sizeof(buffer) - 1); // Write to standard output
return 0;
}
#include <unistd.h>
int main() {
ft_usleep(1000000); // Sleep for 1 second (1,000,000 microseconds)
return 0;
}
#include <sys/time.h>
int main() {
struct timeval tv;
gettimeofday(&tv, NULL);
printf("Seconds: %ld, Microseconds: %ld\n", tv.tv_sec, tv.tv_usec);
return 0;
}
#include <pthread.h>
#include <stdio.h>
void *thread_function(void *arg) {
printf("Thread is running\n");
return NULL;
}
int main() {
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_function, NULL);
pthread_join(thread_id, NULL); // Wait for the thread to finish
return 0;
}
#include <pthread.h>
pthread_mutex_t mutex;
void *thread_function(void *arg) {
pthread_mutex_lock(&mutex);
// Critical section
printf("Thread is in the critical section\n");
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_mutex_init(&mutex, NULL);
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_function, NULL);
pthread_join(thread_id, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
8818 3 is eating 8918 4 is thinking 8918 2 is thinking 9018 1 is sleeping 9018 3 is sleeping 9018 4 has taken a fork 9018 4 has taken a fork 9018 4 is eating 9018 2 has taken a fork 9018 2 has taken a fork 9018 2 is eating 9118 1 is thinking 9118 3 is thinking 9218 2 is sleeping 9218 3 has taken a fork 9218 3 has taken a fork 9218 3 is eating 9218 1 has taken a fork 9218 1 has taken a fork 9218 1 is eating 9218 4 is sleeping 9319 2 is thinking 9319 4 is thinking