简体   繁体   English

python:multiprocessing.Pipe 和在 Windows 上重定向 stderr

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM