【问题标题】:OS process management from ErlangErlang 的操作系统进程管理
【发布时间】:2011-08-11 21:31:23
【问题描述】:

从 Erlang 进行操作系统进程管理的最佳方法是什么?我需要能够生成子 OS 进程,写入孩子的标准输入,从标准输出和标准错误读取,发送终止信号,并获得退出代码的通知。我不认为这对于 erts 中的内容是可能的。

我知道erlexec,但我不知道它是否稳定,或者是否有人真的在愤怒地使用它。还有其他选择吗,还是最好的选择?

【问题讨论】:

    标签: process erlang operating-system


    【解决方案1】:

    Port 程序是最好的方法。端口程序是安全的,不会损害 Erlang VM,如果它们崩溃或行为不端,可以像任何其他 Erlang 进程一样被杀死并重新启动。

    端口驱动程序是不同的,如果它们行为不端,可能会导致整个 Erlang VM 崩溃。

    【讨论】:

    • 好的。 erlexec 是一个为运行任意子进程而设计的端口程序,因此它看起来至少是正确的方法。不过,似乎没有其他人使用过它,这有点奇怪 - 这真的是一个不常见的要求吗?
    • 用几乎任何合理的语言编写端口包装程序都非常简单,C 和 Python 都有用于将术语转换为二进制文件并再次转换回语言原生结构的库。 erlexec 是用于任何任意可执行文件的通用包装程序。如果您想要特定的行为,并且大多数人都这样做,他们会编写自己的端口包装程序。我通常使用 Python,因为它们是小型代理程序,逻辑很少,序列化和反序列化的性能通常不是问题。
    【解决方案2】:

    在 Erlang 中管理操作系统进程的标准方式是ports

    如果选项exit_status 添加到open_port,则生成的操作系统进程的退出状态将作为消息发送:

    1> P = open_port({spawn, "/bin/ls unknown_file_name"}, [exit_status]).
    #Port<0.486>
    /bin/ls: cannot access unknown_file_name: No such file or directory
    2> flush().
    Shell got {#Port<0.486>,{exit_status,2}}
    ok
    

    可以通过向端口发送消息或通过port_command 函数将数据写入生成的操作系统进程的标准输入,标准输出内容将作为消息发送。 (还要注意open_port{line, L}{packet, N} 选项):

    1> P = open_port({spawn, "/bin/cat"}, [stream, binary]).
    #Port<0.486>
    2> true = port_command(P, <<"data">>).
    true
    3> flush().
    Shell got {#Port<0.486>,{data,<<"data">>}}
    ok
    4> true = port_close(P).
    true
    

    Stderr 也可以重定向到 stdout:

    1> P = open_port({spawn, "/bin/ls unknown_file_name"}, [stderr_to_stdout, binary]).
    #Port<0.486>
    2> flush().
    Shell got {#Port<0.486>,
        {data,<<"/bin/ls: cannot access unknown_file_name: No such file or directory\n">>}}
    ok
    

    但是您不能使用端口发送终止信号,但如果您通过向端口发送消息或调用port_close 来关闭端口,外部进程可以通过SIGPIPE 信号退出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-17
      • 2014-05-22
      • 1970-01-01
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      相关资源
      最近更新 更多