Home

Search IconIcon to open search

Philosophers

Multi-threaded programming, yay!

# Useful

# To learn

# Notes

It’s not necessary to use a Mutex for printf when you have only one process running, because it’s thread-safe (I think). See - how to use printf with multiple threads. Also .

usleep can’t take values more than 10^6 because POSIX. But on most systems it will work anyway. More here.

# What I’ve learned

Corner cases can bite you in the ass, hacky ways are dangerous.
Rounding error can be a bitch too. Remember time_passed().

# Problems

# Deadlocks

If we represent each fork with a mutex, and write an algorithm where each philosophers takes his left fork, then his right fork, all philosophers can take their left forks and get stuck. And die.

Solution - parity. For example, each philosopher with an even index can take his right fork, then his left fork. Or even simpler - the first philosopher takes right fork, then left, while others do the opposite (left, then right).

# Starvation

As forks are not prioritized and philosophers don’t speak with each other, it’s not guaranteed that a fork will be taken by a philosopher who needs it most. And he can die.

A hacky solutuion for this particular task:
For even number of philosophers:
Make a small delay at the start of the simulation for philos with (un)even index. That’s it.

For uneven number of philosophers:
Make a small delay at the start for philos with uneven index, and a delay for the last philo: time_to_eat * 2 plus some delta, like 1 ms. And this delay should also be active for the rest of the philos after their first meal.

# Output control

If one philosopher dies, then others shouldn’t output anything to stdout. This would be easy to achieve with close(1), but close() is not on the list of allowed functions, so you have to use a mutex for this.

# Functions

pthread_create()
Create a thread. Returns 0 on success.

pthread_join()
Like wait() for threads. Returns 0 on success.

# Bonus part

Use named semaphores, create with sem_open(). We’re not allowed to use sem_init() anyway, which is required for an unnamed semaphore.