Skip to content

Instantly share code, notes, and snippets.

@wrgoldstein
Created September 11, 2021 15:16
Show Gist options
  • Select an option

  • Save wrgoldstein/a0c18f89f9b540880f35065f84b7e56d to your computer and use it in GitHub Desktop.

Select an option

Save wrgoldstein/a0c18f89f9b540880f35065f84b7e56d to your computer and use it in GitHub Desktop.
defmodule Exstuf do
@doc """
Illustration of the philosopher dining problem.
Reimplementation of https://www.golangprograms.com/go-language/concurrency.html
## Examples
iex> Exstuf.start()
for _ <- 1..5, do: :satisfied
"""
def start do
eaters = [:Mark, :Russell, :Rocky, :Haris, :Root]
forks = [:one, :two, :three, :four, :five]
places = assign_forks(eaters, forks)
# Starts a supervised mutex process
{:ok, _pid} = Supervisor.start_link([{Mutex, name: Fork}], strategy: :one_for_one)
tasks_with_results =
Enum.map(eaters, fn eater -> Task.async(fn -> eat(eater, places) end) end)
|> Task.yield_many()
results =
Enum.map(tasks_with_results, fn {task, res} ->
# Shut down the tasks that did not reply nor exit
res || Task.shutdown(task, :brutal_kill)
end)
for {:ok, res} <- results, do: res
end
@doc "Each eater shares a fork on each side with their neighbor"
def assign_forks(eaters, forks) do
for {p, i} <- Enum.with_index(eaters), do: {p, {Enum.at(forks, i), Enum.at(forks, i - 1)}}
end
@doc "Simulate time spent eating"
def sleep_for_eating do
:timer.sleep(:rand.uniform(500))
end
@doc "Simulate time spent thinking"
def sleep_for_thinking do
:timer.sleep(:rand.uniform(500))
end
def eat(eater, places) do
# Number of times a philosopher eats
hunger = 3
IO.puts("#{eater} sits down!")
{fork1, fork2} = places[eater]
Enum.each(0..hunger, fn _ ->
IO.puts("#{eater} is hungry!")
lock = Mutex.await_all(Fork, [fork1, fork2])
IO.puts("#{eater} is eating!")
sleep_for_eating()
IO.puts("#{eater} done eating, time to think!")
Mutex.release(Fork, lock)
sleep_for_thinking()
end)
:satisfied
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment