首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从命令行执行Erlang代码中的并发示例

问从命令行执行Erlang代码中的并发示例
EN

Stack Overflow用户
提问于 2015-03-07 00:31:41
回答 2查看 333关注 0票数 2

我正在测试了解Erlang用户指南并发编程部分中的代码。

在tut17.erl中,我使用erl -sname ping启动了一个进程,并以al -sname pong作为指导开始了另一个过程。

代码语言:javascript
复制
-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来检查一切正常。

代码语言:javascript
复制
(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示例:

代码语言:javascript
复制
-module(helloworld).
-export([start/0]).

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

我使用以下命令行:

代码语言:javascript
复制
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
  • 来自乒乓节点:erl -noshell -sname pong -s tut17 start_pong -s init stop

但是,当ping结束时,没有打印任何内容,我就从pong获得了这个错误报告。

代码语言:javascript
复制
=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方法相比,每个进程不等待对应方响应,而是在一段时间后停止。可能出什么事了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-07 03:25:39

命令行的参数在使用-s开关时作为原子列表接收,在使用-run开关时作为字符串列表接收。考虑到这一点,让我们考虑一下发生了什么.

此命令是从shell发出的:

代码语言:javascript
复制
erl -noshell -sname ping \
    -s tut17 start_ping pong@smcho \
    -s init stop

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

要从Erlang和system轻松地运行这两种方法,您可以向start_ping/1添加一个子句

代码语言:javascript
复制
start_ping([Pong_Node]) ->
    spawn(tut17, ping, [3, Pong_Node]);
start_ping(Pong_Node) ->
    start_ping([Pong_Node]).
票数 3
EN

Stack Overflow用户

发布于 2015-03-07 05:00:45

需要作出一些改变。

start_ping

根据zxq9的提示,我修改了start_ping函数。

代码语言:javascript
复制
start_ping([Pong_Node]) ->
    io:format("Ping started~n", []),
    spawn(tut17, ping, [3, Pong_Node]);
start_ping(Pong_Node) ->
    start_ping([Pong_Node]).

当进程完成时调用init:stop()。

我不确定这是绝对必要的,但它似乎正在进行这项修改。

代码语言:javascript
复制
ping(0, Pong_Node) ->
    {pong, Pong_Node} ! finished, 
    io:format("ping finished~n", []),
    init:stop();

然后,我可以从shell命令:erl -noshell -sname ping -s tut17 start_ping pong@smcho中删除erl -noshell -sname ping -s tut17 start_ping pong@smcho。

执行命令

乒乓在被调用之前应该被调用。

更新的代码

这是经修订的守则:

代码语言:javascript
复制
-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", []),
    init:stop();
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", []),
            init:stop();
        {ping, Ping_PID} -> 
            io:format("Pong received ping~n", []), 
            Ping_PID ! pong,
            pong() 
    end.

start_pong() ->
    io:format("Pong started~n", []),
    register(pong, spawn(tut17, pong, [])).

start_ping([Pong_Node]) ->
    io:format("Ping started~n", []),
    spawn(tut17, ping, [3, Pong_Node]);
start_ping(Pong_Node) ->
    start_ping([Pong_Node]).

shell命令:

  • 平:erl -noshell -sname ping -s tut17 start_ping pong@smcho
  • 乒乓球:erl -noshell -sname pong -s tut17 start_pong
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28909965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档