当将 stderr 重定向到 /dev/null 并由 multiprocessing.map_async 调用时,子进程 check_output 抛出异常
subprocess check_output throw exception when redirect stderr to /dev/null and called by multiprocessing.map_async
考虑这段代码:
#!/usr/bin/python
import os
import multiprocessing
import subprocess
def search(name):
devnull=open(os.devnull, 'w')
res = subprocess.check_output(
['sleep', name]
#, stderr=devnull # works fine when comment out
)
class Manager(object):
def __init__(self):
self.pool = multiprocessing.Pool(4)
def clean(self):
self.pool.close()
self.pool.join()
def fetch(self, names):
res = self.pool.map_async(search, names)
return res.get(10)
if __name__ == '__main__':
manager = Manager()
manager.fetch([1, 2, 3])
manager.clean()
如果我将 stderr 更改为指向一个临时文件或根本不更改 stderr,代码将正常执行,否则我会收到以下异常:
Traceback (most recent call last):
File "./z.py", line 71, in <module>
manager.fetch([1, 2, 3])
File "./z.py", line 64, in fetch
return res.get(10)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 554, in get
raise self._value
TypeError: execv() arg 2 must contain only strings
谁能解释一下为什么?
根据异常提示,你的问题出在execv()
,实际上是subprocess.check_output
到运行的参数。它告诉您参数数组 必须 是字符串。以下代码会出现相同的错误:
devnull=open(os.devnull, 'w')
subprocess.check_output(["sleep", 1], stderr=devnull)
解决方法很简单——把manager.fetch([1, 2, 3])
改成manager.fetch(["1", "2", "3"])
。
考虑这段代码:
#!/usr/bin/python
import os
import multiprocessing
import subprocess
def search(name):
devnull=open(os.devnull, 'w')
res = subprocess.check_output(
['sleep', name]
#, stderr=devnull # works fine when comment out
)
class Manager(object):
def __init__(self):
self.pool = multiprocessing.Pool(4)
def clean(self):
self.pool.close()
self.pool.join()
def fetch(self, names):
res = self.pool.map_async(search, names)
return res.get(10)
if __name__ == '__main__':
manager = Manager()
manager.fetch([1, 2, 3])
manager.clean()
如果我将 stderr 更改为指向一个临时文件或根本不更改 stderr,代码将正常执行,否则我会收到以下异常:
Traceback (most recent call last):
File "./z.py", line 71, in <module>
manager.fetch([1, 2, 3])
File "./z.py", line 64, in fetch
return res.get(10)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 554, in get
raise self._value
TypeError: execv() arg 2 must contain only strings
谁能解释一下为什么?
根据异常提示,你的问题出在execv()
,实际上是subprocess.check_output
到运行的参数。它告诉您参数数组 必须 是字符串。以下代码会出现相同的错误:
devnull=open(os.devnull, 'w')
subprocess.check_output(["sleep", 1], stderr=devnull)
解决方法很简单——把manager.fetch([1, 2, 3])
改成manager.fetch(["1", "2", "3"])
。