【问题标题】:erlang: to controlling_process(), or not to controlling_process()erlang:控制进程(),或不控制进程()
【发布时间】:2023-03-15 16:55:01
【问题描述】:

考虑以下简单回显服务器的 erlang 代码:

回声监听器:

-module(echo_listener).
-export([start_link/1]).

-define(TCP_OPTIONS, [binary, {packet, 0}, {reuseaddr, true},
                        {keepalive, true}, {backlog, 30}, {active, false}]).

start_link(ListenPort) ->
    {ok, ListenSocket} = gen_tcp:listen(ListenPort, ?TCP_OPTIONS),
    accept_loop(ListenSocket).

accept_loop(ListenSocket) ->
    {ok, ClientSocket} = gen_tcp:accept(ListenSocket),
    Pid = spawn(echo_worker, usher, [ClientSocket]),
    gen_tcp:controlling_process(ClientSocket, Pid),
    accept_loop(ListenSocket).

回声工作者:

-module(echo_worker).
-export([echo/1]).

echo(ClientSocket) ->
    case gen_tcp:recv(ClientSocket, 0) of
        {ok, Data} ->
            gen_tcp:send(ClientSocket, Data),
            echo(ClientSocket);
        {error, closed} ->
            ok
    end.

无论何时接受客户端套接字,回显服务器都会生成一个回显工作者并将客户端套接字直接作为函数参数传递。代码中有controller_process(),但我试过没有调用controlling_process()的代码,也可以。

controlling_process() 的真正目的是什么?什么时候需要?

提前致谢。

【问题讨论】:

    标签: sockets erlang gen-tcp


    【解决方案1】:

    Erlang 文档中提到了 gen_tcp:controlling_process/1:

    为 Socket 分配一个新的控制进程 Pid。控制进程是从套接字接收消息的进程。如果 由当前控制进程以外的任何其他进程调用, {error, not_owner} 返回。

    您使用选项 {active, false} 创建了侦听套接字,并使用 gen_tcp:recv/2 同步读取套接字,因此即使不调用 gen_tcp:controlling_process/1,您的代码也可以工作。但是,如果您想异步接收数据,则必须使用选项 {active, true} 创建侦听套接字。在这种情况下,接受连接的所有者将收到有关传入数据的消息。所以如果你不调用 gen_tcp:controlling_process/1 这些消息将被发送到监听进程而不是工作进程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-31
      • 1970-01-01
      • 2017-10-30
      • 2012-01-17
      • 2013-02-19
      • 2011-02-27
      • 2013-04-13
      • 1970-01-01
      相关资源
      最近更新 更多