con*_*ych 3 multiprocessing python-3.x python-multiprocessing
我正在尝试使用Python的多处理模块来生成一个服务器来接收UDP消息,稍微修改它们,然后将它们传递给以subprocess模块启动的grep进程。由于 Popen 子进程的标准输入接受文件描述符,这就是我想要传递的内容。
我遇到的问题是获取一个与服务器进程通信的文件描述符,我可以将其传递给 grep 子进程。我过去曾使用普通的 os.fork() 和 os.pipe() 完成此操作,但现在我想使用带有 spawn start 方法的多重处理。我尝试从 os.pipe 获取写入描述符,使其可继承,并通过 multiprocess.Process 将其作为参数传递给新进程。当我尝试使用 os.fdopen(fd, 'wb') 在另一个进程中打开它时,我收到错误文件描述符的 OSError 。这是我测试过的代码片段。
def _listen_syslog(ip_address, 端口, write_pipe):
f = os.fdopen(write_pipe, 'wb')
#做一些事情,比如写入文件
def Listen_syslog(ip_address, 端口):
r, w = os.pipe()
os.set_inheritable(w, True)
proc = mp.Process(target=_listen_syslog, args=(ip_address, port, w))
proc.start()
#这个进程不需要写,所以关闭它
os.close(w)
#这是我想传递给 grep 子进程 stdin 的描述符
#在使用 os.fork() 之前,类似的情况已经发生过
返回r
最后,如果无法使用通过 os.pipe() 创建的管道来执行此操作,我可以使用 multiprocessing.Pipe() 并使用连接对象 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())
Run Code Online (Sandbox Code Playgroud)