Erlang 中的进程将调用link/1
或spawn_link
创建与另一个进程的链接。在我正在研究的最近的一个应用程序中,我很好奇一个进程是否有可能在给定的实例中知道它所链接的其他进程的数量。这可能吗 ?他们是 BIF 吗?
然后,当一个链接进程死亡时,我猜如果有可能知道链接进程的数量,这个数字将由运行时系统自动递减。这种机制在处理Parent-Child
Erlang 并发程序中的关系时是理想的,即使是在不涉及supervisors
.
那么,Erlang 进程是否有out-of-the-box
可能通过 BIF 知道链接到它的进程的数量,这样每当一个链接的进程死亡时,这个值就会自动递减under-the-hood
:)?
为了稍微扩展这个问题,考虑一个 gen_server,它将通过handle_info
. 在这部分,它的工作是让dispatch
子进程在任务进入时立即处理。这样做的目的是确保server loop
立即返回以处理下一个请求。现在,子进程异步处理任务,并在请求者死亡之前将回复发送回请求者。在继续之前,请参阅此问题及其答案。
现在,如果为每个由 gen_server 生成的子进程创建一个链接,我想使用这个链接作为计数器。我知道,我知道,每个人都会像“为什么不使用 gen_serverState
,携带一个计数器,然后相应地增加或减少它?" :) 在 gen_server 的某个地方,我有:
handle_info({Sender,Task},State)->
spawn_link(?MODULE,child,[Sender,Task]),
%% At this point, the number of links to the gen_server is incremented
%% by the run-time system
{noreply,State};
handle_info( _ ,State) -> {noreply,State}.
孩子继续这样做:
child(Sender,Task)->
Result = (catch execute_task(Task)),
Sender ! Result,
ok. %% At this point the child process exits,
%% and i expect the link value to be decremented
最后, gen_server 有一个公开的调用,如下所示:
get_no_of_links()-> gen_server:call(?MODULE,links).
handle_call(links, _ ,State)->
%% BIF to get number of instantaneous links expected here
Links = erlang:get_links(), %% This is fake, do not do it at home :)
{reply,Links,State};
handle_call(_ , _ ,State)-> {reply,ok,State}.
现在,有人可能会问自己,真的,为什么有人要这样做?
通常,可以在 gen_server 状态中创建一个整数,然后我们自己来做,或者至少使 gen_server 为 handle_info 类型{'EXIT',ChildPid,_Reason}
,然后服务器会相应地采取行动。我的想法是,如果可以知道链接的数量,我会用它来知道(在给定的时间),有多少子进程仍在忙于工作,这反过来实际上可能有助于预测服务器负载。