0

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

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

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

任何帮助将不胜感激

4

1 回答 1

3

实际上有两种方法可以解决这个问题。
第一个是:控制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. 
于 2013-05-09T07:16:45.470 回答