Last active
November 6, 2020 03:44
-
-
Save kachayev/4634226 to your computer and use it in GitHub Desktop.
Solve "Sleeping Barber Problem" with Erlang (more about problem - http://en.wikipedia.org/wiki/Sleeping_barber_problem)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(barber). | |
-export([run/2, barber/1, clients/1, simulator/2]). | |
-define(CUT_DUTAION, 20). | |
run(RoomSize, Duration) -> | |
% create barber | |
BPid = spawn(?MODULE, barber, [?CUT_DUTAION]), | |
% run simulartor with barber PID | |
SPid = spawn(?MODULE, simulator, [BPid, RoomSize]), | |
% spawn clients generator | |
CSPid = spawn(?MODULE, clients, [SPid]), | |
% create timer to close simulator after duration time | |
timer:send_after(Duration, SPid, {close, CSPid}). | |
barber(Duration) -> | |
receive | |
{client, Simulator} -> | |
timer:sleep(Duration), | |
Simulator ! {barber, done}, | |
barber(Duration) | |
end. | |
clients(Simulator) -> | |
Rnd = 7 + random:uniform(28), % XXX: you can play with constants | |
receive | |
close -> ok | |
after Rnd -> | |
Simulator ! {sim, client}, | |
clients(Simulator) | |
end. | |
simulator({BPid, Status}, {RoomSize, Client, Total}) -> | |
case serve_simulation(self(), {BPid, Status}, {RoomSize, Client, Total}) of | |
{S, C, T} -> simulator({BPid, S}, {RoomSize, C, T}); | |
{close, ClientsGenerator} -> | |
ClientsGenerator ! close, | |
io:format("Closed! Served clients (~p)~n", [Total]), | |
ok | |
end; | |
simulator(Barber, RoomSize) -> | |
simulator({Barber, free}, {RoomSize, 0, 0}). | |
serve_simulation(Me, {BPid, Status}, {RoomSize, Client, Total}) -> | |
receive | |
{sim, client} when Status == free -> | |
io:format("Client goes to barber~n"), | |
BPid ! {client, Me}, | |
{busy, 0, Total}; | |
{sim, client} when Status == busy, RoomSize > Client -> | |
io:format("Client goes to room, new size (~p)~n", [Client+1]), | |
{busy, Client+1, Total}; | |
{sim, client} -> | |
io:format("No free space for client, room size (~p)~n", [Client]), | |
{busy, Client, Total}; | |
{barber, done} when Client > 0 -> | |
io:format("Take client from room, new size (~p)~n", [Client-1]), | |
BPid ! {client, Me}, | |
{busy, Client-1, Total+1}; | |
{barber, done} -> | |
io:format("Barber finished, idle~n", []), | |
{free, 0, Total+1}; | |
{close, ClientsGenerator} -> {close, ClientsGenerator} | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment