gpt4 book ai didi

erlang - 从命令行执行 Erlang 代码中的并发示例

转载 作者:行者123 更新时间:2023-12-01 23:02:49 25 4
gpt4 key购买 nike

我正在测试 Getting Started with Erlang User's Guide 中的代码并发编程部分。

tut17.erl 中,我使用 erl -sname ping 启动了一个进程,并以 al -sname pong 为指导启动了另一个进程描述。

-module(tut17).
-export([start_ping/1, start_pong/0, ping/2, pong/0]).

ping(0, Pong_Node) ->
{pong, Pong_Node} ! finished,
io:format("ping finished~n", []);

ping(N, Pong_Node) ->
{pong, Pong_Node} ! {ping, self()},
receive
pong ->
io:format("Ping received pong~n", [])
end,
ping(N - 1, Pong_Node).

pong() ->
receive
finished -> io:format("Pong finished~n", []);
{ping, Ping_PID} ->
io:format("Pong received ping~n", []),
Ping_PID ! pong,
pong()
end.

start_pong() ->
register(pong, spawn(tut17, pong, [])).

start_ping(Pong_Node) ->
spawn(tut17, ping, [3, Pong_Node]).

从 ping 和 pong 过程中,我可以调用 start_ping 和 start_pong 来检查一切是否正常。

(ping@smcho)1> tut17:start_ping(pong@smcho).
<0.40.0>
Ping received pong
Ping received pong
Ping received pong
ping finished

(pong@smcho)2> tut17:start_pong().
true
Pong received ping
Pong received ping
Pong received ping
Pong finished

我正在尝试从命令行运行相同的代码;对于一个简单的 hello world 示例:

-module(helloworld).
-export([start/0]).

start() ->
io:fwrite("Hello, world!\n").

我使用以下命令行:

erlc helloworld.erl
erl -noshell -s helloworld start -s init stop

所以,我只是尝试了以下操作,但最终崩溃了。

  • 来自 ping 节点:erl -noshell -sname ping -s tut17 start_ping pong@smcho -s init stop
  • 来自 pong 节点:erl -noshell -sname pong -s tut17 start_pong -s init stop

但是,当 pong 结束但没有打印任何内容时,我从 ping 收到此错误报告。

=ERROR REPORT==== 6-Mar-2015::20:29:24 ===
Error in process <0.35.0> on node 'ping@smcho' with exit value:
{badarg,[{tut17,ping,2,[{file,"tut17.erl"},{line,9}]}]}

与REPL方法相比,使用命令行,每个进程不会等待对方响应,而是在一段时间后停止。可能出了什么问题?

最佳答案

使用 -s 开关时,来自命令行的参数以原子列表的形式接收;使用 -run 开关时,以字符串列表的形式接收。考虑到这一点,让我们思考一下会发生什么......

该命令是从 shell 发出的:

erl -noshell -sname ping \
-s tut17 start_ping pong@smcho \
-s init stop

因此,正在使用参数[pong@smcho]调用start_ping/1。然后,它将 ping/2 调用为 ping(3, [pong@smcho]),在第一行中尝试执行 {pong, [pong@ smcho]}! {ping,self()}。因为列表不是消息的有效目标...你的世界爆炸了。

要从 Erlang shell 和系统 shell 轻松运行它,您可以向 start_ping/1 添加一个子句:

start_ping([Pong_Node]) ->
spawn(tut17, ping, [3, Pong_Node]);
start_ping(Pong_Node) ->
start_ping([Pong_Node]).

关于erlang - 从命令行执行 Erlang 代码中的并发示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28909965/

25 4 0
文章推荐: r - 一次汇总多个变量一组
文章推荐: java - Web UI 自动化测试适用于桌面 Chrome,但可以在 Android Chrome 中找到元素
文章推荐: php - 使用 Magento 2.3.3 p1 后遇到的问题
文章推荐: Java 8 使用对象子级的字段将 List 转换为 Map