Erlang环控制器进程相关

时间:2013-05-08 10:31:35

标签: process erlang

我是Erlang的新手,我有以下要解决的作业问题:

“控制”过程必须提供用户函数go(N,M) 生成{1,2,...,M}中M个随机整数的列表L, 设置N个进程的环(所谓的“worker”)并发送一个令牌 对第一个工人。当worker k收到令牌时,它会发送一个令牌 消息{eat,self()}来控制并将令牌发送给下一个工作者。

当控件收到消息{eat,Pid}时,它撤回列表的头部H. L并将元组{H,Pid}附加到结果列表中。当列表L为空时,控制 向终止工作人员的环发送停止消息并打印结果 列表。

任何帮助都是apreciated

1 个答案:

答案 0 :(得分:2)

实际上有两种方法可以解决这个问题 第一个是: 控制spawns环中的所有工人都是解决方案:

-module(ring). 
-export([start/3, create/4]). 

start(M, N, Message) -> 
        create(undef, N, M, Message). 

create(Parent, 0, M, Message) -> 
        Parent ! {created, self()}, 
        evaluate(Parent, M, Message); 

create(Parent, N, M, Message) -> 
        Child = spawn(?MODULE, create, [self(), N-1, M, Message]), 
        io:format("~w ~w created~n", [Child, N]), 
        evaluate(Parent, M, Message). 

evaluate(undef, M, Message) -> 
        receive 
                {created, Last} -> 
                        Last ! Message, 
                        io:format("~w sent ~w to ~w~n", [self(), Message, Last]), 
                        evaluate(Last, M-1, Message) 
        end; 

evaluate(Parent, 0, _) -> 
        receive 
                Msg -> 
                        io:format("~w received ~w~n", [self(), Msg]), 
                        Parent ! stop, 
                        io:format("~w sent ~w to ~w~n", [self(), stop, Parent]) 
        end; 

evaluate(Parent, M, Message) -> 
        receive 
                {created, Last} -> 
                        Parent ! {created, Last}, 
                        evaluate(Parent, M, Message); 
                Message -> 
                        io:format("~w received ~w~n", [self(), Message]), 
                        Parent ! Message, 
                        io:format("~w sent ~w to ~w~n", [self(), Message, Parent]), 
                        evaluate(Parent, M-1, Message) 
        end. 

第二个是:控制spawns只有环中的第一个工人。每个新工人    在戒指中,但是最后一个,产生了下一个工人:

-module(ring). 
-export([start/3, start_process/1, start_process/2]). 

start(M, N, Message) -> 
    Pid = spawn(ring, start_process, [N]), 
    Pid ! {message, Message, M}, 
    ok. 

start_process(Count) -> 
    % This is the first spawned process - send its 
    % pid down the chain so the last process knows who its 
    % next pid is. 
    io:format("~p: Spawned ~p~n", [self(), Count]), 
    Pid = spawn(ring, start_process, [Count-1, self()]), 
    loop(Pid). 

start_process(0, Last) -> 
    % This is the last process 
    io:format("~p: Linking to last ~p~n", [self(), Last]), 
    loop(Last); 
start_process(Count, Last) -> 
    io:format("~p: Spawned ~p~n", [self(), Count]), 
    Pid = spawn(ring, start_process, [Count-1, Last]), 
    loop(Pid). 

loop(NextPid) -> 
    receive 
        {message, _,   0} -> true; 
        {message, Msg, M} -> 
            io:format("~p (~p) ~p~n", [Msg, self(), M]), 
            NextPid ! {message, Msg, M-1}, 
            loop(NextPid) 
    end.