【发布时间】:2018-08-02 02:17:57
【问题描述】:
我正在使用 learnyousomeerlang site 慢慢学习 erlang 语言,目前我在“Rage Against The Finite-State Machines”一章,该章节构建并描述了 trade_fsm.erl 的工作原理。作为我学习过程的一部分,我决定为这个系统编写一个界面,您可以在其中通过输入控制台命令来控制交易双方。我认为我在写这篇文章方面做得不错,但是由于某种原因我无法理解,每当我尝试开始交易时,客户就会崩溃。事情是这样的:
5> z3:init("a", "b").
true
6> z3:display_pids().
First player pid: {<0.64.0>}
Second player pid: {<0.65.0>}.
done
7> z3:p1_propose_trade().
{a}: asking user <0.65.0> for a trade
{b}: <0.64.0> asked for a trade negotiation
done
8> z3:display_pids().
done
9>
这是我的代码:
-module(z3).
-compile(export_all).
-record(state, {player1,
player2,
p1items=[],
p2items=[],
p1state,
p2state,
p1name="Carl",
p2name="FutureJim"}).
init(FirstName, SecondName) ->
{ok, Pid1} = trade_fsm:start_link(FirstName),
{ok, Pid2} = trade_fsm:start_link(SecondName),
S = #state{p1name=FirstName, p2name=SecondName,
player1=Pid1, player2=Pid2,
p1state=idle, p2state=idle},
register(?MODULE, spawn(?MODULE, loop, [S])).
display_pids() ->
?MODULE ! display_pids,
done.
p1_propose_trade() ->
?MODULE ! {wanna_trade, p1},
done.
p2_accept_trade() ->
?MODULE ! {accept_trade, p2},
done.
loop(S=#state{}) ->
receive
display_pids ->
io:format("First player pid: {~p}~nSecond player pid: {~p}.~n", [S#state.player1, S#state.player2]),
loop(S);
{wanna_trade, Player} ->
case Player of
p1 ->
trade_fsm:trade(S#state.player1, S#state.player2);
p2 ->
trade_fsm:trade(S#state.player2, S#state.player1);
_ ->
io:format("[Debug:] Invalid player.~n")
end,
loop(S);
{accept_trade, Player} ->
case Player of
p1 ->
trade_fsm:accept_trade(S#state.player1);
p2 ->
trade_fsm:accept_trade(S#state.player2);
_ ->
io:format("[Debug:] Invalid player.~n")
end,
loop(S);
_ ->
io:format("[Debug:] Received invalid command.~n"),
loop(S)
end.
谁能告诉我为什么这段代码会失败以及应该如何实现?
【问题讨论】:
-
您在崩溃时遇到的错误是什么?我可以看到您的控制台输出中没有崩溃。
-
@matov 这是问题的一部分,没有错误消息,但 Pids 死了,不能再被“撞”(Pid !Msg)
标签: concurrency interface erlang