[英]python: multiprocessing.Pipe and redirecting stderr on Windows
I've a main process where I open a multiprocessing.Pipe(False)
and send the writing end to a worker Process.我有一个主进程,我在其中打开一个multiprocessing.Pipe(False)
并将写入结束发送到一个工作进程。 Then, in the worker process, I run a Java program using subprocces.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
.然后,在工作进程中,我使用subprocces.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
运行 Java 程序。 I need to redirect the error of this subprocess to the writing end of multiprocessing.Pipe
我需要将此子进程的错误重定向到multiprocessing.Pipe
的写入端
For this I referred to this answer by Ilija as this is exactly what I want to achieve, but on my machine(Windows), it throws OSError: [Errno 9] Bad file descriptor
为此,我参考了 Ilija 的这个答案,因为这正是我想要实现的,但是在我的机器(Windows)上,它抛出OSError: [Errno 9] Bad file descriptor
Machine details:机器详情:
OS - Windows 10 (64bit)操作系统 - Windows 10(64 位)
Python version - 3.7.4 Python 版本 - 3.7.4
Code:代码:
Method 1 ( Ilija's answer )方法一(伊利亚的回答)
def worker(w_conn):
os.dup2(w_conn.fileno(), 2)
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
sp.wait()
w_conn.close()
def main():
r_conn, w_conn = multiprocessing.Pipe(False)
process = multiprocessing.Process(target=worker, args=(w_conn,))
process.start()
while not r_conn.poll() and not w_conn.closed:
# Do stuff
else:
# Read error from r_conn, and handle it
r_conn.close()
process.join()
if __name__=='__main__':
main()
Error:错误:
Process Process-1:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 297, in _bootstrap
self.run()
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\User\Desktop\Workspace\Error.py", line 14, in worker
os.dup2(w_conn.fileno(), 2)
OSError: [Errno 9] Bad file descriptor
Method 2: In worker function, sending w_conn as argument to Popen方法二:在worker函数中,将w_conn作为参数发送给Popen
def worker(w_conn):
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=w_conn)
sp.wait()
w_conn.close()
Error:错误:
Process Process-1:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 297, in _bootstrap
self.run()
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\User\Desktop\Workspace\Error.py", line 13, in worker
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=w_conn)
File "C:\ProgramData\Anaconda3\lib\subprocess.py", line 728, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\ProgramData\Anaconda3\lib\subprocess.py", line 1077, in _get_handles
errwrite = msvcrt.get_osfhandle(stderr.fileno())
OSError: [Errno 9] Bad file descriptor
Is there any workaround/alternate method to achive this on Windows?是否有任何解决方法/替代方法可以在 Windows 上实现此目的?
I still don't know why "Method 1" is not working.我仍然不知道为什么“方法 1”不起作用。 Any information regarding this will be appreciated.任何有关这方面的信息将不胜感激。
"Method 2" is wrong altogether as we can't use Connection
object (returned by multiprocessing.Pipe()
) as a file handle in subprocess.Popen
. “方法 2”完全错误,因为我们不能使用Connection
对象(由multiprocessing.Pipe()
返回)作为subprocess.Popen
的文件句柄。
What works is checking for data in stderr
of subprocess sp
and sending the data through w_conn
to main process.有效的是检查子进程sp
stderr
中的数据并通过w_conn
将数据发送到主进程。
def worker(w_conn):
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sp.wait()
if sp.stderr.seek(0, io.SEEK_END)>0:
w_conn.send(sp.stderr.read())
w_conn.close()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.