Filòsof 4

text/x-erlang filosof4.erl — 3.4 KB

Continguts del fitxer

-module(filosof4).
-export([dinar/2]).
 
 
iniciarFil(N, N, LlistaFil, Cicles) ->
	io:format("Creat el filosof ~p~n",[N]),
	Pid = spawn(fun()-> filosof(N, element(N, LlistaFil), Cicles) end),
	[Pid];

iniciarFil(I, N, LlistaFil, Cicles) ->
	io:format("Creat el filosof ~p~n",[I]),
	Pid = spawn(fun()-> filosof(I, element(I, LlistaFil), Cicles) end),
	[Pid] ++ iniciarFil(I+1, N, LlistaFil, Cicles).

	
crearLlistaEstats(N, _Estat, N) ->
	[];
crearLlistaEstats(N, Estat, I) ->
	[{I+1, Estat}]++crearLlistaEstats(N, Estat, I+1).

crearLlistaEstats(N, Estat) ->
	crearLlistaEstats(N, Estat, 0).

filosof(Num, Nom, 0) -> 	
	io:format("~s marxa.~n", [Nom]),
	cambrer!{final, Num},
	ok;

filosof(Num, Nom, Cycle) ->
	io:format("~s està pensant.~n", [Nom]),
	%timer:sleep(rand:uniform(1000)),
	timer:sleep(100),
	io:format("~s te gana.~n", [Nom]),
	cambrer!{tincGana, Num, self()},
	receive
		{menja, Num} -> ok
	end,
	io:format("~s està menjant************************.~n", [Nom]),
	timer:sleep(rand:uniform(1000)),
	io:format("~s ha deixat de menjar.~n", [Nom]),
	cambrer!{fiMenjar, Num},
	filosof(Num, Nom, Cycle-1).
 
	
mirarEstatD(Estat, I, N) ->
	if 
		I >= N -> Y = I-N+1;
		true -> Y = I + 1
	end,
	{value, {_,EstatDreta}} = lists:keysearch(Y, 1, Estat),
	EstatDreta.

mirarEstatE(Estat, I, N) ->
	if 
		I =< 1 -> Y = I-1+N;
		true -> Y = I -1
	end,
	{value, {_,EstatEsque}} = lists:keysearch(Y, 1, Estat),
	EstatEsque.

mirarEstatVei(Estat, I, N, LPids) ->
	% Mirar si el filosof vol menjar
	if 
		I == 0 -> Y = N;
		I == N+1 -> Y = 1;
		true -> Y = I
	end,
	{value, {_,EstatFil}} = lists:keysearch(Y, 1, Estat),
	if 
		EstatFil == tincGana ->
			EstatD = mirarEstatD(Estat, Y, N),
			EstatE = mirarEstatE(Estat, Y, N),
			if 
				(EstatD /= menjant) and (EstatE /= menjant) ->
					Pid = lists:nth(Y, LPids),
					Pid!{menja, Y},
					NouEstat = lists:keyreplace(Y, 1, Estat, {Y, menjant});
				true ->
					NouEstat = Estat
			end;
		true ->
			NouEstat = Estat
	end,
	NouEstat.
	

cambrer(_Estat, 0, _N, _LPids) -> ok;
cambrer(Estat, Vius, N, LPids) ->
	receive
		{tincGana, I, Pid} -> 
			NouEstat = lists:keyreplace(I, 1, Estat, {I, tincGana}),
			EstatDreta = mirarEstatD(Estat, I, N),
			EstatEsque = mirarEstatE(Estat, I, N),
			if 
				(EstatDreta /= menjant) and (EstatEsque /= menjant) ->
					Pid!{menja, I},
					cambrer(lists:keyreplace(I, 1, Estat, {I, menjant}), Vius, N, LPids);
				true ->
					cambrer(NouEstat, Vius, N, LPids)
			end;
		{final, _Num} ->
			io:format ("Queden a taula: ~p filòsof ~n", [Vius-1]),
			cambrer(Estat, Vius-1, N, LPids);
		{fiMenjar, I} -> 
			NouEstat = lists:keyreplace(I, 1, Estat, {I, pensant}),
			EstatM1 = mirarEstatVei(NouEstat, I+1, N, LPids),
			EstatM2 = mirarEstatVei(EstatM1, I-1, N, LPids),
			cambrer(EstatM2, Vius, N, LPids)
	end.
			
 
dinar(N, _Cicles) when N > 5 ->
	io:format("Com a molt poden haver-hi 5 filosof ~n");

dinar(N, Cicles) ->	
		LlistaFil = {'Aristotle', 'Kant', 'Spinoza', 'Marx', 'Russel'},
		% Crear el semafor per modificar l'estat dels  filosof.
		register(cambrer, self()),
		% Crear els N filosof
		LlistaProFil = iniciarFil(1, N, LlistaFil, Cicles),
		% Gestionar qui ha de menjar
		Estat = crearLlistaEstats(N, pensant),
		%Estat = lists:duplicate(N,{pensant}),
		Vius = N,
		cambrer(Estat, Vius, N, LlistaProFil),
		% Esperar la recepció de N finals
		%finalFil(N),
		io:format("Menjador tancat.~n").