Filòsof 2

text/x-erlang filosof2.erl — 2.3 KB

Continguts del fitxer

-module(filosof2).
-export([dinar/2, initSem/0, lliure/0, ocupat/1]).
 
%sleep(T) ->
%  receive
%after T ->
%		true
%	end.
 
 
% Implementació del semafor
initSem() ->
	lliure().

ocupat(Pid) ->
	receive	
		{signal, Pid} -> lliure()
	end.	

lliure() ->
	receive
		{wait, Pid} ->
			Pid! ok,
			ocupat(Pid);
		stop -> finalitzar()
	end.

finalitzar() ->
	receive
		{wait, Pid} ->
			exit(Pid, kill),
			finalitzar()
		after	
			0 -> ok
	end.

signal(Pid) ->
	Pid!{signal, self()},
	ok.

wait(Pid) ->
	Pid!{wait, self()},
	receive
		ok -> ok
	end.
stop(Pid) -> Pid!stop.
	
iniciarSemafors(N, N, Llista) ->
	Llista;
iniciarSemafors(I, N, Llista) ->
	iniciarSemafors( I+1, N, Llista++[spawn(?MODULE, initSem, [])]).

iniciarFil(N, N, _LlistaFil, _Cicles, _LlistaSem, _Pid) ->
	ok;

iniciarFil(I, N, LlistaFil, Cicles, LlistaSem, Pid) ->
	spawn(fun()-> filosof(I, element(I+1, LlistaFil), Cicles, LlistaSem, N, Pid) end),
	iniciarFil(I+1, N, LlistaFil, Cicles, LlistaSem, Pid).

	
finalFil(0) -> ok;
finalFil(I) ->
	receive
		final -> io:format("Quedan ~p filosof~n", [I-1])
	end,
	finalFil(I-1).
finalSem(0, _LlistaSem) -> ok;
finalSem(I, LlistaSem) ->
 	PidSem = lists:nth(I, LlistaSem),
	stop(PidSem),
	finalSem(I-1, LlistaSem).
	
filosof(_Num, Nom, 0, _Sem, _N, Pid) -> 	
	io:format("~s marxa.~n", [Nom]),
	Pid!final,
	ok;
 
 
filosof(Num, Nom, Cycle, LlistaSem, N, Pid) ->
	io:format("~s està pensant.~n", [Nom]),
	timer:sleep(rand:uniform(1000)),
	%timer:sleep(100),
	io:format("~s te gana.~n", [Nom]),
 	PidSemE = lists:nth(Num+1, LlistaSem),
 	PidSemD = lists:nth(((Num+1) rem N)+1, LlistaSem),
	wait(PidSemE),
	wait(PidSemD),
	io:format("~s està menjant************************.~n", [Nom]),
	timer:sleep(rand:uniform(1000)),
	signal(PidSemE),
	signal(PidSemD),
	io:format("~s ha deixat de menjar.~n", [Nom]),
	filosof(Num, Nom, Cycle-1, LlistaSem, N, Pid).
 

dinar(N, Cicles) ->	
		LlistaFil = {'Aristotle', 'Kant', 'Spinoza', 'Marx', 'Russel'},
		% Iniciar els N semafors
		LlistaSem = iniciarSemafors(0, N, []),
		Pid = self(),
		% Crear els N filosof
		iniciarFil(0, N, LlistaFil, Cicles, LlistaSem, Pid),
		
		% Esperar la recepció de N finals
		finalFil(N),
		io:format("Menjador tancat.~n"),
		% Finalitzar els N semafors
		finalSem(N, LlistaSem).