group_leader的设计和用途

一直对erlang的group_leader这个概念很困惑,因为*nix系统也有类似的名词但是只是和进程组管理有关系。查了很多文档才知道,erlang的group_leader的设计意图和作用,解释如下:

先看下着段代码运作:

log_group_leader(OGL) ->
    receive Msg ->
            io:format(user, "Got message ~p~n",[Msg]),
            OGL ! Msg,
            log_group_leader(OGL)
    end.

ioclient(NGL) ->
    group_leader(NGL, self()),
    io:format("Hello World~n"),
    io:format("Hello again~n").

iotest() ->
    OldGroupLeader = group_leader(),
    NewGroupLeader = spawn(?MODULE, log_group_leader, [OldGroupLeader]),
    spawn(?MODULE, ioclient, [NewGroupLeader]).

说白了group_leader就是决定erlang的io控制台的输出到那个进程。

这个特性很有帮助。我们在做服务器程序的时候 会有大量的诊断信息通过类似printf打印需要输出到控制台查看。 代码里东一块西一块都是诊断代码, 而且一旦程序调试完毕 我们可能不在需要这些信息污染环境。这个是单机的情况,对于分布式的情况就更复杂,很难把其他主机上打出的诊断信息汇总到一个地方集中查看。

group_leader就是解决这个问题的。 erlang里面的io:format之类的函数执行的时候最早输出会被重定向到该进程的group_leader进程去,而且进程是位置无关的,也就是说在其他主机上的信息都可以汇总。

有了这个特性 比如说我在其他的机器上执行条rpc命令 这个命令的结果是会被截获 传送回来的 而不是要到目标主机的终端上显示。

group_leader是继承的,每当spawn一个进程的时候,会自动继承父进程的这个属性。rpc的实现上也很大努力保证了这个语义不变。

在实践中也要注意这个特性的副作用,就是: 你用rpc执行的命令 就是想在目标机器上显示结果 但是看不到 因为被截获了。


你可能感兴趣的:(erlang)