如何为erlang消息赋予不同的优先级

如何为erlang消息赋予不同的优先级,erlang,Erlang,在《erlang编程》一书和《堆栈溢出问题》中,我看到我们可以使用以下方法为邮箱中的erlang消息赋予不同的优先级: 我尝试用以下代码实现类似的功能: -module(mytest). -export([start/0, test/0]). start() -> register(?MODULE, spawn(fun() -> do_receive() end)). do_receive() -> receive {high_p, Mess

在《erlang编程》一书和《堆栈溢出问题》中,我看到我们可以使用以下方法为邮箱中的erlang消息赋予不同的优先级:

我尝试用以下代码实现类似的功能:

-module(mytest).
-export([start/0, test/0]).

start() ->
    register(?MODULE, spawn(fun() -> do_receive() end)).

do_receive() ->
    receive
        {high_p, Message} ->
            io:format("High priority: ~p~n", [Message]),
            do_receive()
    after 0 ->
            receive
                {low_p, Message} ->
                    io:format("Low priority: ~p~n", [Message]),
                    do_receive()
            end
    end.

test() ->
    mytest ! {high_p, msg1},
    mytest ! {low_p, msg2},
    mytest ! {high_p, msg3}.
但结果是:

1> mytest:start().
true
2> mytest:test(). 
Low priority: msg2
{high_p,msg3}
High priority: msg1
High priority: msg3
这似乎不对,所以我将代码更改为:

do_receive() ->
    receive
        {high_p, Message} ->
            io:format("High priority: ~p~n", [Message]),
            do_receive()
    after 0 ->
            receive
                {high_p, _} = Other ->
                    self() ! Other,
                    do_receive();
                {low_p, Message} ->
                    io:format("Low priority: ~p~n", [Message]),
                    do_receive()
            end
    end.
结果如下(所有高优先级消息都在低优先级消息之前打印)


这是实现我目标的正确方法吗?在gen_server handle_info/2中可以实现不同的优先级吗?

在第一个程序中发生的是:

  • 在“接收高优先级消息”状态下生成接收器
  • 他找不到高优先级消息,因此进入“接收低优先级消息”状态
  • 您发送了高优先级消息,但未被识别
  • 您发送了一条低优先级消息,它被识别
  • 然后,接收器循环并进入“高优先级消息”状态,并识别消息
  • 因此,甚至可能会出现死锁,接收者将拥有大量高优先级消息,但无法处理它们,因为他被困在低优先级状态

    因此,我认为您的方法(与您链接的问题的答案类似)更好。 优化:由于您收到高优先级消息,因此无需再次发送(并导致额外开销):


    顺便问一下,我能在handle_info中实现优先级吗?@user601836我不太确定,sorry@user601836你是说在gen_服务器或gen_fsm中?不,你不能,反正也不容易喜欢这里。消息接收在gen_server循环中为您完成,因此将按照消息到达的顺序调用
    handle_info
    handle_call
    handle_cast
    。您可以如上所述明确检查
    handle\u info
    中的高优先级消息,但在其他事件发生之前,这不会发生。这是使用gen_服务器的缺点之一,您会失去接收消息的显式控制。感谢您指出这一点,我将坚持使用自己的自定义流程,使用proc_lib:start_link启动它
    1> mytest:start().
    true
    2> mytest:test(). 
    High priority: msg3
    {high_p,msg3}
    High priority: msg1
    Low priority: msg2
    
    do_receive() ->
        receive
            {high_p, Message} ->
                do_high(Message)
        after 0 ->
                receive
                    {high_p, Message} ->
                        do_high(Message);
                    {low_p, Message} ->
                        io:format("Low priority: ~p~n", [Message])
                end
        end,
        do_receive().
    
    do_high(Message) ->
        io:format("High priority: ~p~n", [Message]).