handle_info保证在初始化之后的一个进程中首先执行超时0? [英] Is handle_info guaranteed to executed first in a process after init with timeout 0?

查看:156
本文介绍了handle_info保证在初始化之后的一个进程中首先执行超时0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是一个初始化代码:

$ b我有一个奇怪的错误报告,让我认为在gen_server初始化之前调用了一些调用。
$ b

  init([ResourceId]) - > 
process_flag(trap_exit,true),
{ok,{not_initialized,ResourceId},0}。

这是应该初始化资源的handle_info。

  handle_info(timeout,{not_initialized,ResourceId}) - > 
Resource = data_store:get_resource(ResourceId),
{noreply,Resource,?CACHE_TIMEOUT};

data_store的返回值:get_resource(ResourceId)是#resouce {}记录,用于匹配所有的handle_call方法。



从过程开始仍然没有初始化一个功能子句的崩溃报告。

  = CRASH REPORT ==== 1-Feb-2013 :: 14:20:03 === 
crasher:
初始调用:gbanga_resources:init / 1
pid:< 0.11772.0>
registered_name:[]
exception exit:{function_clause,
[{gbanga_resources,terminate,
[{function_clause,
[{gbanga_resources,handle_call,
[get_resource,
{< 0.11658.0>,#Ref< 0.0.0.240914>},
{not_initialized,12697711}],
[{file,src / gbanga_resources.erl },
{line,120}]},
{gen_server,handle_msg,5,
[{file,gen_server.erl},{line,588}]},
{proc_lib,init_p_do_apply,3,
[{file,proc_lib.erl},{line,227}]}],
{not_initialized,12697711}],
[{文件,SRC / GBA nga_resources.erl},{line,176}]},
{gen_server,terminate,6,
[{file,gen_server.erl},{line,722}]},
{proc_lib,init_p_do_apply,3,
[{file,proc_lib.erl},{line,227}]}]}
在函数gen_server中:terminate / 6(gen_server.erl,line
祖先:[gbanga_resources_sup,gbanga_workers_sup,< 0.92.0]
messages:[{'$ gen_call',{< 0.11638.0>,#Ref <0.0.0.240915} ,get_resource},
{'$ gen_call',{< 0.11633.0>,#Ref< 0.0.0.240916>},get_resource}]
links:[< 0.6609.0>]
字典:[]

如果在任何handle_call之前调用handle_info超时allways都不应该发生



有没有人知道为什么会发生这种情况?

解决方案

?不,超时是像任何其他消息。如果在init函数的中间,你会收到另一个进程的消息,你可能会先处理该消息。



这就是说,init函数 em>用于OTP进程 ,如gen_server与调用进程同步,这意味着在您收到Pid之前,该进程将完成其初始化功能,使其他进程发送极其困难消息给它之前它有机会执行超时。



当然,我不建议为此行为使用超时。它将会发生什么样的定义,因为当从init返回时,该过程是多或少的产生,Erlang中的定时器不能保证准确地触发(定时器:睡眠(5000)将在<至少五秒钟,不到五秒钟)。而是将消息发送到 self();这使得进程可以立即知道它有工作要做,因为在 init返回之前,您的邮箱中的邮件将会起作用。


I am getting a strange error report that makes me think some calls are called before the gen_server initialization.

Here is the init code:

init([ResourceId]) ->
    process_flag(trap_exit, true),
    {ok, {not_initialized, ResourceId}, 0}.

Here is the handle_info that should initialize the resource.

handle_info(timeout, {not_initialized, ResourceId}) ->
    Resource = data_store:get_resource(ResourceId),
    {noreply, Resource, ?CACHE_TIMEOUT};

the return value of data_store:get_resource(ResourceId) is the #resouce{} record, used to match all the handle_call methods.

The crash report with a function clause since the process is still not initialized.

=CRASH REPORT==== 1-Feb-2013::14:20:03 ===
crasher:
  initial call: gbanga_resources:init/1
  pid: <0.11772.0>  
  registered_name: []
  exception exit: {function_clause,
                      [{gbanga_resources,terminate,
                           [{function_clause,
                                [{gbanga_resources,handle_call,
                                     [get_resource,
                                      {<0.11658.0>,#Ref<0.0.0.240914>},
                                      {not_initialized,12697711}],
                                     [{file,"src/gbanga_resources.erl"},
                                      {line,120}]},
                                 {gen_server,handle_msg,5,
                                     [{file,"gen_server.erl"},{line,588}]},
                                 {proc_lib,init_p_do_apply,3,
                                     [{file,"proc_lib.erl"},{line,227}]}]},
                            {not_initialized,12697711}],
                           [{file,"src/gbanga_resources.erl"},{line,176}]},
                       {gen_server,terminate,6,
                           [{file,"gen_server.erl"},{line,722}]},
                       {proc_lib,init_p_do_apply,3,
                           [{file,"proc_lib.erl"},{line,227}]}]}
    in function  gen_server:terminate/6 (gen_server.erl, line 725)
  ancestors: [gbanga_resources_sup,gbanga_workers_sup,<0.92.0>]
  messages: [{'$gen_call',{<0.11638.0>,#Ref<0.0.0.240915>},get_resource},
                {'$gen_call',{<0.11633.0>,#Ref<0.0.0.240916>},get_resource}]
  links: [<0.6609.0>]
  dictionary: []

This should never happens if the handle_info timeout allways is called before any handle_call.

Does anyone knows why this is happening ?

解决方案

Guaranteed? No. The timeout is a message like any other. If during the middle of the init function you receive a message from another process, you will likely process that message first.

That being said, the init function for OTP processes like gen_server is synchronous from the calling process, meaning that the process will have finished its init function by the time you receive the Pid, making it exceedingly difficult for another process to send a message to it before it has a chance to execute the timeout.

Of course, I would not recommend using a timeout for this behavior. It's less well-defined what will happen, because the process is more-or-less yielding when it returns from init, and timers in Erlang are not guaranteed to fire exactly on time (timer:sleep(5000) will sleep at least five seconds, not exactly five seconds). Instead, send a message to self(); this lets the process know immediately that it has work to do, as the message winds up in your mailbox before init returns.

这篇关于handle_info保证在初始化之后的一个进程中首先执行超时0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆