subprocess check_output在将stderr重定向到/ dev / null并由multiprocessing.map_async

时间:2015-08-14 13:09:36

标签: python subprocess python-multiprocessing

考虑以下代码:

#!/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

任何人都可以解释原因吗?

1 个答案:

答案 0 :(得分:2)

正如异常所示,您的问题出现在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"])