一直对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执行的命令 就是想在目标机器上显示结果 但是看不到 因为被截获了。
先看下着段代码运作:
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执行的命令 就是想在目标机器上显示结果 但是看不到 因为被截获了。