Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

50.12.1Rendez-vous

We define the error type to return from threads:

We create two synchronize channels, with no buffers. The absence of buffer will force the sender to block until a receiver takes its message (this is called a rendez-vous):

Couldn't automatically determine type of variable `tx2`.
Please give it an explicit type.

We start first the thread 2 that will count the odd numbers. At each step of the loop, it:

  1. Waits for a message from thread 1.

  2. Prints its number.

  3. Sends a message to thread 1 in order to unlock it.

The thread 1 counts the even numbers. In each loop step, it:

  1. Prints its number.

  2. Sends a message to thread 2 in order to unlock it.

  3. Waits for a message from thread 2.

Finally, we wait for the two threads to finish:

50.12.2Dining philosophers problem

We start with importing the various needed types:

We create a function that creates and runs a diner. It will allow us to run multiple diners. It takes as arguments:

  1. n: the number of philosophers and chopsticks.

  2. n_bites: the number of bites to eat.

  3. think_ms: the time spent to think.

We need an array to store the philosopher threads and chopsticks mutexes, and a mutex on the common dish, then we initialize the chopsticks. We run a loop to spawn the threads, in which the index i is used to get the indices of the two chopsticks. We clone the reference on the common dish, then the references on the needed chopsticks, and spawn the ithi^{th} thread. Inside the closure, we first initialize two variables to count the number of bites eaten by the philosopher, and the time spent to think. The main body of the closure is an infinite loop that alternates between an eating phase (trying to lock the left & right chopsticks, then the common dish, to eat one bite) and a thinking phase (the thread sleeps during a fixed time). When the philosopher is done, we return a sum-up of its actions. Finally, we wait for the threads to terminate:

We add a convenient function to print the results returned by diner():

We run a first time the diner() function with 5 philosophers, 500 bites to eat and a thinking time of 1 ms, in order to check if no deadlocks appear:

We run then the diner() function with 5 philosophers, 5 bites to eat and a thinking time of 1 ms, in order to check if each philosopher eats exactly one bite: