Perl - 与 fork/exec'ed 进程通信
Posted
技术标签:
【中文标题】Perl - 与 fork/exec\'ed 进程通信【英文标题】:Perl - Communicating with a fork/exec'ed processPerl - 与 fork/exec'ed 进程通信 【发布时间】:2012-12-27 04:05:17 【问题描述】:我正在设计一个服务器,它将通过 fork / exec 的四个“管理器”(它们自己的服务器进程)进行初始化,然后接受来自客户端的连接,fork / 执行“奴隶”与客户沟通。在其生命周期中,slave 将与 manager 建立连接并向他们发送工作请求。
我的问题是关于启动管理器的。每个都可能需要一些时间来初始化(几分钟),我不希望主服务器在初始化之前继续接受客户端。最好的方法是什么?我是否应该探索让经理在准备好后向主服务器发出信号?我是否应该让管理人员与主服务器建立套接字连接 - 可能在与客户端连接的端口不同的端口上 - 并在准备好时发送消息?还是别的什么?
【问题讨论】:
【参考方案1】:我很想在分叉四个管理器之前创建一个管道。当管理器准备好时,它可以将其 PID 写入管道并关闭它。主服务器可以延迟打开其侦听端口,直到至少有一个管理器表明它已准备好。如果它在所有管理器报告已准备好执行现役之前从管道中获取 EOF,那么它知道至少有一个管理器未能启动并且可以采取适当的措施(记录错误并退出?)。写入管道的消息通常被原子处理;也就是说,如果消息足够短,一个进程写入的内容不会与另一个进程写入的内容交错。
对于某些变体,您可以每个经理有一个管道;然后你必须决定你将如何轮询或选择哪个管道有消息等待。你可以决定经理们在表明他们已经准备好之后不关闭管道;他们可以保持打开状态,并在准备好时写入适当的“PID 准备就绪”,稍后再写入其他状态消息(“PID 退出”、“PID 太忙”、“PID 正在喝咖啡休息时间”……)。
还有很多其他的 IPC 机制可以使用,每一种都有自己的优点和缺点。很大程度上取决于管理者需要与主人沟通什么(以及主人是否需要与特定管理者沟通)。可以肯定使用套接字;消息队列也可以。如果您的通信需求很简单,信号量集可能会起作用。名单还在继续。
【讨论】:
你说的是管道还是命名管道?管理人员将被分叉,然后被执行——一旦 exec() 发生,它不会失去对“匿名管道”的访问权限吗? 我说的是(匿名)管道,而不是 FIFO(命名管道)。不;当 exec 发生时,进程不会失去对匿名管道的访问权限……您认为 shell 在执行程序时如何与匿名管道一起工作?当然,您需要知道在 exec 进程中读取或写入哪个文件描述符。在 shell 的上下文中,这通常是标准输入或标准输出。这可能是也可能不是您的管理器程序的选项,但您可以向它们传递参数(例如-d 3
)以指示要使用的文件描述符。【参考方案2】:
你想到的是 FIFO 管道。 mknod 传统上用于创建它们。管道有 2 个文件描述符,一个用于读取,一个用于写入......如果需要,它们可以阻止它......
【讨论】:
又名命名管道?是的,我想这会奏效。 exec() 中的参数之一可能是管道的名称。但到目前为止,我还没有发现任何提及管道同时具有读取和写入文件描述符... 不要将mknod
用于FIFO;使用mkfifo
! (实际上,不要使用mknod
,句号。您很少需要这样做;您必须安装新的块或字符设备才能使用mknod
。)以上是关于Perl - 与 fork/exec'ed 进程通信的主要内容,如果未能解决你的问题,请参考以下文章
Perl 行为差异关闭由 open() 产生的子进程与 IPC::Open3