Проверка, является ли почтовый ящик пустым?в эрланге - PullRequest
6 голосов
/ 21 октября 2011

Мне нужно сделать проверку, которая возвращает true или false, в зависимости от того, есть ли у текущего процесса какое-либо сообщение в его почтовом ящике в erlang.

Ответы [ 3 ]

13 голосов
/ 23 октября 2011

Вы можете использовать process_info/2 BIF для доступа к информации о процессе, включая очередь сообщений. Так

process_info(self(), message_queue_len) => {message_queue_len,Length}

и

process_info(self(), messages) => {messages,MessageList}

Второй неэффективен, если в очереди много сообщений, поскольку список создается для каждого вызова (хотя, конечно, это не сообщения). Есть много интересных вещей, которые вы можете узнать о процессе. Нет никаких ограничений на то, какой процесс вы можете получить информацию, вы можете сделать это для любого процесса.

4 голосов
/ 21 октября 2011

Вы должны быть в состоянии использовать 0 для времени ожидания receive. В приведенном ниже примере он попытается вывести сообщение из очереди, если его там нет, он вернет атом false.

1> receive _ -> true  
1> after 0 ->
1> false
1> end.
empty

Имейте в виду, что будет принимать сообщение.

Еще один способ - использовать erlang:process_info, но это предположительно только для отладки.

6> {message_queue_len, QueueLen} = erlang:process_info(self(), message_queue_len).
{message_queue_len,0}
7> QueueLen.
0

Всего сейчас:

16> HasMessages = fun(Pid) ->                                           
16>     element(2, erlang:process_info(Pid, message_queue_len)) > 0     
16> end.
#Fun<erl_eval.6.80247286>
17> HasMessages(self()).                                                                      
false
18> self() ! test.
test
19> HasMessages(self()).
true
1 голос
/ 22 октября 2011

Внутри есть средства для проверки наличия сообщения в почтовом ящике процесса.

Но будьте осторожны!Я не думаю, что Erlang предназначен для такого использования:

{module, hasMsg}.
{exports, [{module_info,0},{module_info,1},{hasMsg,0},{peekMsg,1},{lastMsg,1}]}.
{attributes, []}.
{labels, 17}.

{function, hasMsg, 0, 2}.
    {label,1}.
        {func_info,{atom,hasMsg},{atom,hasMsg},0}.
    {label,2}.
        {loop_rec,{f,4},{x,0}}.
        {move,{atom,true},{x,0}}.
        return.
    {label,3}.
        {loop_rec_end,{f,2}}.
    {label,4}.
        timeout.
        {move,{atom,false},{x,0}}.
        return.

{function, peekMsg, 1, 6}.
    {label,5}.
        {func_info,{atom,hasMsg},{atom,peekMsg},1}.
    {label,6}.
        {loop_rec,{f,8},{x,0}}.
        return.
    {label,7}.
        {loop_rec_end,{f,6}}.
    {label,8}.
        timeout.
        return.

{function, lastMsg, 1, 10}.
    {label,9}.
        {func_info,{atom,hasMsg},{atom,lastMsg},1}.
    {label,10}.
        {loop_rec,{f,12},{x,0}}.
        {test,is_eq_exact,{f,11},[]}.
    {label,11}.
        {loop_rec_end,{f,10}}.
    {label,12}.
        timeout.
        return.

{function, module_info, 0, 14}.
    {label,13}.
        {func_info,{atom,hasMsg},{atom,module_info},0}.
    {label,14}.
        {move,{atom,hasMsg},{x,0}}.
        {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.

{function, module_info, 1, 16}.
    {label,15}.
        {func_info,{atom,hasMsg},{atom,module_info},1}.
    {label,16}.
        {move,{x,0},{x,1}}.
        {move,{atom,hasMsg},{x,0}}.
        {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.

Компиляция: erlc +from_asm hasMsg.S.

Модуль hasMsg содержит:

  • hasMsg/0 возвращает логическое значение, если в почтовом ящике есть сообщения.
  • peekMsg/1 возвращает самое старое сообщение без его удаления.Возвращает аргумент, если почтовый ящик пуст.
  • lastMsg/1 возвращает самое новое сообщение, не удаляя его.Возвращает аргумент, если почтовый ящик пуст.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...