如何在Python中将文件描述符从父进程传递给子进程?

9 投票
4 回答
7987 浏览
提问于 2025-04-15 23:39

我正在使用多进程模块,并通过池来启动多个工作进程。但是,在父进程中打开的文件描述符在工作进程中被关闭了。我希望它们能够保持打开状态!有没有办法让文件描述符在父进程和子进程之间共享呢?

4 个回答

4

还有一个叫做 multiprocess 的项目,它是 multiprocessing 的一个分支。这个 multiprocessdill 替代了 pickledill 可以处理文件描述符,这样 multiprocess 就能很方便地在不同的进程之间传递这些文件描述符。

>>> f = open('test.txt', 'w')
>>> _ = map(f.write, 'hello world')
>>> f.close()
>>> import multiprocess as mp
>>> p = mp.Pool()
>>> f = open('test.txt', 'r')
>>> p.apply(lambda x:x, f)
'hello world'
>>> f.read()
'hello world'
>>> f.close()
10

在Python 2和Python 3中,有一些函数可以用来发送和接收文件描述符,这些函数在multiprocessing.reduction这个模块里。

下面是一个示例代码(适用于Python 2和Python 3):

import multiprocessing
import os

# Before fork
child_pipe, parent_pipe = multiprocessing.Pipe(duplex=True)

child_pid = os.fork()

if child_pid:
    # Inside parent process
    import multiprocessing.reduction
    import socket
    # has socket_to_pass socket object which want to pass to the child
    socket_to_pass = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    socket_to_pass.connect("/dev/log")
    # child_pid argument to send_handle() can be arbitrary on Unix,
    # on Windows it has to be child PID
    multiprocessing.reduction.send_handle(parent_pipe, socket_to_pass.fileno(), child_pid)
    socket_to_pass.send("hello from the parent process\n".encode())
else:
    # Inside child process
    import multiprocessing.reduction
    import socket
    import os
    fd = multiprocessing.reduction.recv_handle(child_pipe)
    # rebuild the socket object from fd
    received_socket = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
    # socket.fromfd() duplicates fd, so we can close the received one
    os.close(fd)
    # and now you can communicate using the received socket
    received_socket.send("hello from the child process\n".encode())
-1

我不知道有什么方法可以在不同的进程之间共享文件描述符。如果有这种方法,它很可能是特定于某个操作系统的。

我猜你需要在其他层面上共享数据。

撰写回答