Python 3.x Python多处理中的共享文件描述符

Python 3.x Python多处理中的共享文件描述符,python-3.x,multiprocessing,python-multiprocessing,Python 3.x,Multiprocessing,Python Multiprocessing,我正在尝试使用Pythons多处理模块生成一个服务器来接收UDP消息,稍微修改它们,然后将它们传递给一个由子流程模块启动的grep流程。因为Popen子进程的stdin接受一个文件描述符,所以我想传递它 我遇到的问题是获取一个与服务器进程通信的文件描述符,我可以将其传递给grep子进程。我以前使用纯os.fork()和os.pipe()完成了这项工作,但现在我想使用spawn start方法进行多处理。我曾尝试从os.pipe获取一个写描述符,使其可继承,并通过multiprocess.proc

我正在尝试使用Pythons多处理模块生成一个服务器来接收UDP消息,稍微修改它们,然后将它们传递给一个由子流程模块启动的grep流程。因为Popen子进程的stdin接受一个文件描述符,所以我想传递它

我遇到的问题是获取一个与服务器进程通信的文件描述符,我可以将其传递给grep子进程。我以前使用纯os.fork()和os.pipe()完成了这项工作,但现在我想使用spawn start方法进行多处理。我曾尝试从os.pipe获取一个写描述符,使其可继承,并通过multiprocess.process将其作为参数传递给一个新进程。当我尝试在另一个进程中用os.fdopen(fd,'wb')打开它时,我会得到一个错误文件描述符的操作系统错误。下面是我测试过的代码片段

def _listen_syslog(ip_address, port, write_pipe): f = os.fdopen(write_pipe, 'wb') #do stuff like write to the file def listen_syslog(ip_address, port): r, w = os.pipe() os.set_inheritable(w, True) proc = mp.Process(target=_listen_syslog, args=(ip_address, port, w)) proc.start() #this process doesn't need to write, so close it os.close(w) #this is the descriptor I want to pass to a grep subprocess stdin #a similar scenario has worked before using os.fork() return r def_listen_syslog(ip地址、端口、写入管道): f=os.fdopen(写入管道“wb”) #做一些事情,比如写文件 def listen_系统日志(ip_地址、端口): r、 w=os.pipe() os.set_可继承(w,True) proc=mp.Process(target=\u listen\u syslog,args=(ip地址,端口,w)) 程序启动() #这个进程不需要写,所以关闭它 操作系统关闭(w) #这是我想要传递给grep子进程stdin的描述符 #在使用os.fork()之前,类似的场景也曾出现过 返回r
最后,如果无法使用通过os.pipe()创建的管道执行此操作,我是否可以使用multiprocessing.pipe(),并使用connections objects fileno()函数中的文件描述符直接使用?更重要的是,只要我不将连接对象用于其他用途,这样做安全吗?

我找到了一个解决方案。我还没有弄清楚如何使用
os.pipe()
,但是如果我使用
multiprocessing.pipe()
,我可以通过调用每个连接对象的
fileno()
函数来使用每个连接对象的文件描述符。我发现的另一件事是,如果您想在连接对象不再被引用后使用文件描述符,则必须对每个文件描述符调用
os.dup()
,否则它们将关闭,当连接对象被垃圾收集时,您将得到一个错误的文件描述符错误

import multiprocessing as mp

def _listen_syslog(ip_address, port, write_pipe):
    f = os.fdopen(write_pipe.fileno(), 'wb')
    #do stuff
    

def listen_syslog(ip_address, port):
    r, w = mp.Pipe(False)
    proc = mp.Process(target=_listen_syslog, args=(ip_address, port, w))
    proc.start()
    return os.dup(r.fileno())