2017-03-23 76 views
1

我有一個接受命令行參數的Python腳本job.py。該腳本使用Python包subprocess來運行一些外部程序。腳本和外部程序都是順序的(即沒有MPI,openMP等)。我想運行這個腳本4次,每次使用不同的命令行參數。我的處理器有4個內核,因此我想同時運行所有4個實例。如果我打開4個終端並在單獨的終端中運行腳本的每個實例,它將完美工作,並且我得到我想要的。如何運行使用subprocess.call的同一Python腳本的多個實例

現在我想讓自己更容易啓動4個實例,以便我可以使用單個終端的單個命令完成所有這些操作。爲此,我使用bash腳本batch.sh

python job.py 4 0 & 
python job.py 4 1 & 
python job.py 4 2 & 
python job.py 4 3 & 

這不起作用。事實證明,subprocess是這裏的罪魁禍首。所有Python代碼完美運行,直到它擊中subprocess.call之後,我得到:

[1]+ Stopped     python job.py 4 0 

所以我怎麼看它,就是我想在後臺運行job.pyjob.py本身試圖在後臺運行別的東西通過subprocess。這顯然不起作用,原因我不明白。

有沒有辦法多次運行job.py而不需要多個終端?

編輯#1

關於建議我嘗試了multiprocessingthreadthreading包。在最好的情況下,只有一個實例正常運行。我嘗試了一個醜陋的解決方法,它工作。我做了一個bash腳本這會打開一個新的終端的每個實例:

konsole -e python job.py 4 0 
konsole -e python job.py 4 1 
konsole -e python job.py 4 2 
konsole -e python job.py 4 3 

編輯#2

下面是一個使用subprocess.call實際功能(注:subprocess導入爲sp)。

def run_case(path): 
    case = path['case'] 
    os.chdir(case) 
    cmd = '{foam}; {solver} >log.{solver} 2>&1'.format(foam=CONFIG['FOAM'], 
                 solver=CONFIG['SOLVER']) 
    sp.call(['/bin/bash', '-i', '-c', cmd]) 

讓我填補了空白點:

  • CONFIG是一個全局定義字典。
  • CONFIG['FOAM'] = 'of40'這是我的.bashrc中的一個別名,用於源文件屬於我正在運行的二進制文件。
  • CONFIG['SOLVER'] = 'simpleFoam'這是我正在運行的二進制文件。

編輯#3

我終於得到它與這個

def run_case(): 
    case = CONFIG['PATH']['case'] 
    os.chdir(case) 
    cmd = 'source {foam}; {solver} >log.simpleFoam 2>&1'.format(foam=CONFIG['FOAM'], 
                   solver=CONFIG['SOLVER']) 
    sp.call([cmd], shell=True, executable='/bin/bash') 

該解決方案的工作是制定雙方shell=Trueexecutable='/bin/bash'而是包括/bin/bash在實際的命令行傳遞給shell。注意:foam現在是到文件而不是別名的路徑。

+0

'停止'可能意味着'job.py'的實例完成。 – Apalala

+3

我不認爲這與'subprocess'模塊有什麼關係。我認爲你正在運行的程序想要寫入'stdout',並且接收到一個'SIGTTOU',因爲你已經將它放在後臺,所以它無法訪問控制終端。這是標準行爲。從程序捕獲輸出(設置'stdout = subprocess.PIPE'和'stderr = subprocess.PIPE')可能會起作用,但是您需要正確處理程序輸出(請參閱'subprocess.Popen'和'communic''方法)。 – larsks

+0

你應該使用線程來訪問你的不同內核。 https://www.tutorialspoint.com/python/python_multithreading.htm – Tobey

回答

2

您可以從Python的內並行:

import multiprocessing 
import subprocess 

def run_job(spec): 
    ... 
    if spec ...: 
     subprocess.call(...) 

def run_all_jobs(specs): 
    pool = multiprocessing.Pool() 
    pool.map(run_job, specs) 

它有讓您監控的優勢/日誌/調試並行。

+0

我試過了,但它只會運行其中一個作業。爲了運行池中的其他人,我必須在終端中鍵入'fg'。不知何故'subprocess.call'具有鎖定行爲,因爲'subprocess.call'之前的所有內容都按預期運行。如果我註釋掉每個'subprocess.call',那麼所有的作業都會運行直到完成(自然沒有做任何有用的事情)。 – mtgoncalves

+0

你用'subprocess.call()'調用了什麼?你使用'shell = True'嗎? – Apalala

+0

我嘗試了'shell'設置爲'True'和'False'。請參閱OP中的** EDIT#2 **以查看使用'subprocess.call'的函數。 – mtgoncalves

相關問題