Controlling Process

昨天写测试代码的时候,遇到了一些疑惑,那就是erlang中control process.

在使用gen_tcp进行开发的时候,我们可以通过调用gen_tcp:accept和gen_tcp:connect而产生socket,此时调用所在的process,称为这个socket的control process. control process的生存期控制着socket的生存期,如果control process结束了,那么Socket也会被关闭.要解除这个约束的方法是调用gen_tcp:controlling_process/2, 为Socket设置一个新的control process.

参看erlang-china中a pitfall in passing socket via processes 一文:

    在花了大半天“追根究底”之后,发现原因是这样的:“socket 是通过 port 实现的,如果这个 port 的 owner process 退出,那么这个 port 也会关闭”。

让我们在通过一个例子来更深的理解一下:

-module(r3).
-compile(export_all).

  start() ->
      spawn(r3, start, ["www.erlang.org", 80]).

  start(RHost, RPort) ->
      io:format("start:pid=~p~n", [self()]),
      {ok, Sock} = gen_tcp:connect(RHost, RPort, [list, {packet, 0}, {active, false}, {reuseaddr, true}]),
      io:format("start:socket=~p~n", [erlang:port_info(Sock)]),
      Test = spawn(r3, test, [Sock]),
      %% 注释A: 让Sock的contrl process等待一会,从而允许test process使用Sock进行工作
      %%receive
      %%after 1000 ->
      %%	ok
      %%end.
      %% 注释B: gen_tcp:controlling_process(Sock, Test).

  test(Sock) ->
     %%注释C: gen_tcp:controlling_process(Sock, self()),
      io:format("test:pid=~p~n", [self()]),
      io:format("socket=~p~n", [erlang:port_info(Sock)]),
      ok = gen_tcp:send(Sock, "GET / HTTP/1.0\r\n\r\n"),
      case gen_tcp:recv(Sock, 0) of
          {ok, Pack} ->
              io:format("recv:ok:~p~n", [Pack]);
          Any ->
              io:format("recv:~p~n", [Any])
      end,
      ok = gen_tcp:close(Sock).


上面的几个spwan只是为了测试socket在不同process之间处理的情况,因此上面代码不应该是你写程序参考的代码.

如果没有A,B,C三个注释,那么这个module会运行出错,提示Sock undef, 这就是control process起的坏作用,其退出导致socket被关闭. 让我们一步一步的验证我们的想法吧.

1,如果仅仅去除注释A, 我们的control process在spawn(r3, test, [Sock])后,会等待1秒钟,这样Sock不会随着control process的结束而关闭,因此我们可以获取www.erlang.org的内容

2,如果仅仅去除注释B, 那么我们通过controlling_process/2,将Sock的control process设置为Test,这样我们也可以收到www.erlang.org的内容

3,如果仅仅去除注释C,那么我们几乎不能收到任何内容就出现了错误,因为control process退出的速度要大于Test process启动的速度. 我们也可以通过process间发送消息的方法做到两个线程间的同步,从而确保Test process获取Sock的控制权以后原线程在退出. 动手试验一下吧.

你可能感兴趣的:(C++,c,socket,erlang,C#)