1

嗨,我是 Erlang 的新手,我刚开始学习流程。这里我有一个典型的流程循环:

loop(X,Y,Z) ->
    receive
        {do} ->
            NewX = X+1,
            NewY = Y+1,
            NewZ = Z+1,

            Product = NewX * NewY * NewZ,

            % do something

            loop(NewX,NewY,NewZ)
    end.

比如说,我如何Product从函数中获取最新值get_product()?我知道消息传递将是合乎逻辑的选择,但有没有更优化的方法来提取价值?

4

2 回答 2

2

认为这是你想要的:

-module(lab).

-compile(export_all).

start() ->
    InitialState = {1,1,1},
    Pid = spawn(?MODULE, loop, [InitialState]),
    register(server, Pid).

loop(State) ->
    {X, Y, Z} = State,
    receive
        tick ->
            NewX = X+1,
            NewY = Y+1,
            NewZ = Z+1,
            NewState = {NewX, NewY, NewZ},
            loop(NewState);
        {get_product, From} ->
            Product = X * Y * Z,
            From ! Product,
            loop(State);
        _ ->
            io:format("Unknown message received.~n"),
            loop(State)
    end.

get_product() ->
    server ! {get_product, self()},
    receive
        Product ->
            Product
    end.

tick() ->
    server ! tick.

在 Erlang shell 中:

1> c(lab).
{ok,lab}
2> lab:start().
true
3> lab:get_product().
1
4> lab:tick().       
tick
5> lab:get_product().
8
6> lab:tick().       
tick
7> lab:tick().
tick
8> lab:get_product().
64
于 2013-09-15T07:19:50.797 回答
2

以下是我所知道的 Erlang 进程之间通信的方法,以及我对它们相对性能的(可能是错误的)评估。

  1. 消息传递。这种方法将满足您的大部分需求。我不知道它是如何实际实现的,但从我的角度来看,它应该与将指针放入队列并取回它一样快。
  2. 外部方法,例如套接字文件管道。这些方法对于不同节点之间的通信可能更快,具体取决于您解决的问题、您的解决方案和程序将在其中执行的环境。Erlang 中的节点间通信是通过 TCP 连接完成的,所以如果您想使用自己编写的代码要通过 TCP 套接字进行通信,您应该非常努力地超越 Erlang 的实现。
  3. 电子交易系统,Dets。假设最佳可能实现,这些方法不会比消息传递 (ETS) 或文件 (Dets) 更快。
  4. NIF。您可以编写一种方法来保存 NIF 库中的值,并编写一种方法来检索它。这个有可能优于消息传递,因为您可以将一个值保存到一个变量中并在需要时将其返回,并且它在receive.
  5. 处理字典。您可以使用调用获取另一个进程字典erlang:process_info(Pid, dictionary),在该Pid过程中您可以使用调用将值放入该字典中put(Key, Value)

此外,如果您想加快 Erlang 应用程序的速度,请查看HiPE,它可能会有所帮助。

在从消息传递切换到此列表中的任何内容以提高速度之前,您应该先测量它

于 2013-09-15T14:49:16.370 回答