我有我運行一個命令行程序,我管文字作爲參數:python中map.pool的用法是什麼?
somecommand.exe < someparameters_tin.txt
它運行了一段時間(通常是一個小時的良好的比例爲幾小時),然後將結果寫入多個文本文件。我試圖編寫一個腳本來同時啓動其中幾個,使用多核心機器上的所有內核。在其他操作系統上,我會分叉,但是這在Windows的很多腳本語言中都沒有實現。 Python的多處理看起來可能會有所斬獲,所以我想我會試一試,儘管我根本不知道python。我希望有人能告訴我我做錯了什麼。
我寫了一個腳本(下面),我指向一個目錄,如果找到可執行文件和輸入文件,並使用pool.map和一個n池以及使用調用的函數啓動它們。我看到的是,最初(第一組n進程啓動)看起來很好,使用n個內核100%。但後來我看到這些進程閒置,沒有使用或僅佔其CPU的百分之幾。那裏總是有n個流程,但他們沒有太多的工作。它似乎發生在編寫輸出數據文件時,一旦它開始一切都陷入泥潭,整體核心利用率從幾個百分點到50-60%的偶爾峯值,但從未接近100%。
如果我可以附加它(編輯:我不能,至少現在)這裏是過程的運行時間陰謀。較低的曲線是當我打開n個命令提示符並手動保存n個進程時,輕鬆保持計算機接近100%。 (這條線是規則的,在32個不同的過程中,從一個參數緩慢增加到接近0到0.7個小時)。上面一行是這個腳本的一些版本的結果 - 運行時間平均膨脹大約0.2小時,並且是更不容易預測,就像我已經取得了底線並增加了0.2 +一個隨機數。
下面是劇情的鏈接: Run time plot
編輯:現在我想我可以添加的情節。
我在做什麼錯?
from multiprocessing import Pool, cpu_count, Lock
from subprocess import call
import glob, time, os, shlex, sys
import random
def launchCmd(s):
mypid = os.getpid()
try:
retcode = call(s, shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e
if __name__ == '__main__':
# ******************************************************************
# change this to the path you have the executable and input files in
mypath = 'E:\\foo\\test\\'
# ******************************************************************
startpath = os.getcwd()
os.chdir(mypath)
# find list of input files
flist = glob.glob('*_tin.txt')
elist = glob.glob('*.exe')
# this will not act as expected if there's more than one .exe file in that directory!
ex = elist[0] + ' < '
print
print 'START'
print 'Path: ', mypath
print 'Using the executable: ', ex
nin = len(flist)
print 'Found ',nin,' input files.'
print '-----'
clist = [ex + s for s in flist]
cores = cpu_count()
print 'CPU count ', cores
print '-----'
# ******************************************************
# change this to the number of processes you want to run
nproc = cores -1
# ******************************************************
pool = Pool(processes=nproc, maxtasksperchild=1) # start nproc worker processes
# mychunk = int(nin/nproc) # this didn't help
# list.reverse(clist) # neither did this, or randomizing the list
pool.map(launchCmd, clist) # launch processes
os.chdir(startpath) # return to original working directory
print 'Done'
你看起來像你真的知道你在做什麼;這看起來像一個自稱爲總新手的好Python。一個問題:當CPU空閒時,硬盤是否超級忙?從理論上講,如果你的進程產生了大量的輸出,那麼在等待磁盤寫入所有內容時,進程可能大部分是空閒的。如果緩存由於某種原因不起作用,情況尤其如此。 – steveha
看來(如資源監視器報告的),當CPU使用率下降(這是在第一個進程開始寫入其輸出時發生)時,磁盤活動會出現峯值,然後在所有進程完成之前保持接近100%。磁盤隊列也會變爲50.我很好奇爲什麼會出現這種情況,但不是當我從多個命令行手動執行相同的命令時 - 看起來似乎正在共享某些東西(很糟糕)。 – Brian
我應該補充一點:我不在乎這些過程以什麼順序完成。在這個例子中,我正在嘗試最短的那個先運行。隨機或反轉訂單可能會有所幫助,但不會產生很大的差異。 – Brian