2016-09-30 68 views
0

我一直在嘗試使用subprocess32.Popen但這會導致我的系統崩潰(CPU 100%)。所以,我有以下代碼:subprocess32.Popen崩潰(CPU 100%)

import subprocess32 as subprocess 

for i in some_iterable: 
    output = subprocess.Popen(['/path/to/sh/file/script.sh',i[0],i[1],i[2],i[3],i[4],i[5]],shell=False,stdin=None,stdout=None,stderr=None,close_fds=True) 

在此之前,我有以下幾點:

import subprocess32 as subprocess 
for i in some_iterable: 
    output subprocess.check_output(['/path/to/sh/file/script.sh',i[0],i[1],i[2],i[3],i[4],i[5]]) 

..我曾與這個沒有問題 - 除了它已經死了緩慢。

隨着Popen我發現這很快 - 但是我的CPU在幾秒內變得太過100%,系統崩潰 - 迫使硬重啓。

我想知道我在做什麼是造成Popen崩潰?

在Linux上,Python2.7如果有幫助的話。

感謝。

+0

你的腳本究竟做了什麼,在這種情況下'some_iterable'有多大? 'check_output()'等待每個進程完成,'Popen()'不會,所以你正在處理多個並行進程。所以如果你的腳本消耗了大量資源(內存不足),這可能是系統變得不穩定的原因。 – mata

+0

'some_iterable'大約有2百萬個條目..我明白你在說什麼,但我該如何避免這種情況? – JohnJ

回答

0

問題是,您正試圖一次啓動2個毫秒的進程,這會阻止您的系統。

解決方案是使用池來限制一次可以運行的最大進程數,並等待每個進程完成。對於這種情況下,你開始的子進程,並等待他們(IO約束),從multiprocessing.dummy模塊線程池會做:因爲你使用

import multiprocessing.dummy as mp 
import subprocess32 as subprocess 

def run_script(args): 
    args = ['/path/to/sh/file/script.sh'] + args 
    process = subprocess.Popen(args, close_fds=True) 
    # wait for exit and return exit code 
    # or use check_output() instead of Popen() if you need to process the output. 
    return process.wait() 

# use a pool of 10 to allow at most 10 processes to be alive at a time 
threadpool = mp.Pool(10) 

# pool.imap or pool.imap_unordered should be used to avoid creating a list 
# of all 2M return values in memory 
results = threadpool.imap_unordered(run_script, some_iterable) 
for result in results: 
    ... # process result if needed 

我省略了大部分的參數Popen無論如何都是默認值。如果你的腳本正在進行交互式工作,如果它主要做IO(網絡訪問,寫入文件......),那麼池的大小可能應該在你可用的CPU核心範圍內,然後可能更多。

+0

如何在'threadpool.imap_unordered(run_script,some_iterable)'內將參數傳遞給'run_script'?其次,我使用一個csv閱讀器來讀取200萬條記錄,並且我有類似'\t reader = csv.reader(open(filex),delimiter ='|') \t對於閱讀器中的行:'在這種情況下, 'some_iterable'是?以前,我把每一個'行'都傳遞給了Popen流程..不知道我現在怎麼才能實現這個想法.. – JohnJ

+0

我試圖在這裏實現這個:http://pastebin.com/jKka6cHG但是這是錯誤...不知道如何用'runscript'調用'threadpool' ... – JohnJ

+0

'map'函數需要一個函數來運行一個參數並迭代,併爲列表中的每個項目調用該函數。所以你不需要在一個循環中調用函數,你可以傳遞'reader'作爲參數迭代器,就像[this](http://pastebin.com/WCRDCzfB) – mata