python - 在 Python 中 fork 时父子进程之间的通信

标签 python fork ipc

我试图让一个 Python 程序同时运行一个处理循环和一个结果广播服务,使用对 os.fork() 的调用,类似于

pid = os.fork()
if pid == 0:
    time.sleep(3)
    keep_updating_some_value_while_parent_is_running()
else:
    broadcast_value()

此处 keep_updating_some_value_while_parent_is_running() 由子级执行,存储一些值,只要父级运行,它就会不断更新。它实际上将值写入磁盘,以便父级可以轻松访问它。它通过检查它运行的 Web 服务是否可用来检测父级是否正在运行。

broadcast_value() 运行一个网络服务,当被查询时它从磁盘读取最新的值并提供它。

此实现效果很好,但由于以下几个原因并不令人满意:

  1. time.sleep(3) 是必需的,因为网络服务需要 一些启动时间。根本无法保证服务会在 3 秒内启动并运行,但另一方面可能会早得多。

  2. 通过磁盘共享数据并不总是一个好的选择,甚至不可能(因此该解决方案不能很好地推广)。

  3. 通过检查 Web 服务是否可用来检测父进程是否正在运行并不是最佳选择,而且对于不同类型的进程(无法如此轻松地自动轮询),这根本行不通。此外,Web 服务可能运行良好,但存在暂时的可用性问题。

  4. 解决方案取决于操作系统。

  5. 当 child 因某种原因失败或退出时, parent 将继续 运行(这可能是所需的行为,但并非总是如此)。

我想要的是某种方式让子进程知道父进程何时启动和运行,何时停止,并让父进程根据请求获得子进程计算的最新值,最好是在一种独立于操作系统的方式。也欢迎涉及非标准库的解决方案。

最佳答案

我建议使用 multiprocessing 而不是 os.fork(),因为它会为您处理很多细节。特别是它提供了 Manager类,它提供了一种在进程之间共享数据的好方法。您将启动一个 Process 来处理获取数据,另一个用于执行 Web 服务,然后将 Manager 提供的共享数据字典传递给它们。然后主进程只负责设置所有这些(并等待进程完成 - 否则 Manager 中断)。

这可能是这样的:

import time
from multiprocessing import Manager, Process

def get_data():
    """ Does the actual work of getting the updating value. """

def update_the_data(shared_dict):
    while not shared_dict.get('server_started'):
        time.sleep(.1)
    while True:
        shared_dict['data'] = get_data()
        shared_dict['data_timestamp'] = time.time()
        time.sleep(LOOP_DELAY)


def serve_the_data(shared_dict):
    server = initialize_server() # whatever this looks like
    shared_dict['server_started'] = True
    while True:
        server.serve_with_timeout()
        if time.time() - shared_dict['data_timestamp'] > 30:
            # child hasn't updated data for 30 seconds; problem?
            handle_child_problem()


if __name__ == '__main__':
    manager = Manager()
    shared_dict = manager.dict()
    processes = [Process(target=update_the_data, args=(shared_dict,)),
        Process(target=serve_the_data, args=(shared_dict,))]
    for process in processes:
        process.start()
    for process in processes:
        process.join()

关于python - 在 Python 中 fork 时父子进程之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48672348/

相关文章:

C# 等效于另一个进程的postthreadmessage

c++ - C++ 和 Python 之间的简单 IPC(跨平台)

python - 在 Linux 中通过命名管道发送数据 block

python - 将 OpenCV 文档添加到 PyCharm

Python MySQLdb LOAD LOCAL INFILE问题

python - 使用通用数据源同步 QListWidget

c - 如何让子进程交替访问和更改相同的值

计算子进程fork()的进程运行时间

c++ - 如何终止 C++ 中的 fork 进程?

php - 如何使 PHP 脚本实时响应数据库插入?