簡體   English   中英

os.waitpid()似乎無法正常工作

[英]os.waitpid() seems not working properly

我有三個函數(兩個循環)定義,我想從command_1通過command_3處理一大塊文件,一旦完成,使用相同的工作流程返回處理另一個塊。

偽代碼顯示在這里

實際代碼更長並且有效:

def run(cmd):
  try:
    subprocess.Popen(command,shell='True')
  except:
    exit()

def run_chunk(chunk,command,flag=False)
  for file in chunk
    cmd = eval(command+'("' + bam + ')"') 
    run(cmd)
def main():
  chunks = [[chunk1],[chunk2]...]
  for chunk in chunks:
    run_chunk(chunk, command_1, True)
    os.waitpid(-1,0)
    run_chunk(chunk, command_2, True)
    os.waitpid(-1,0)
    run_chunk(chunk, command_3, True)
    os.waitpid(-1,0)

注意:eval將返回一個字符串,這是“run”函數的命令

我的問題是,當我運行command_1時,os.waitpid()似乎正在工作; 一旦command_1完成,程序進入command_2,在我看來command_2將在轉到command_3之前等待,但main函數中的外部循環將立即執行command_1(我不想要)

誰能發現代碼中的任何錯誤? 非常感謝!

通過查看API ,我認為問題可能與您等待子進程的方式有關。 我建議實際上嘗試等待孩子的特定pid( waitpid(child1) )。 您可以從Popen電話中獲取該信息。

如果pid大於0,則waitpid()請求該特定進程的狀態信息。 如果pid為0,則請求是針對當前進程的進程組中的任何子進程的狀態。 如果pid為-1,則該請求與當前進程的任何子進程有關。 如果pid小於-1,則為進程組中的任何進程請求狀態-pid(pid的絕對值)。

每次調用run_chunk可能會產生許多子子run_chunk os.waitpid(-1, 0)將等待任何子os.waitpid(-1, 0)結束。 如果chunk有許多文件,則os.waitpid(-1, 0)將在所有子子os.waitpid(-1, 0)完成之前返回。 因此,后續調用run_chunk可能發生得太早。

如果您希望每個調用按順序run ,則在run添加對proc.communicate()的調用:

def run(cmd):
    try:
        proc = subprocess.Popen(cmd, shell=True)
        proc.communicate()
    except:
        exit()

如果你想給所有呼叫run所產生run_chunk到同時發生的話,或許最簡單的方法是使用多處理線程池

import multiprocessing.pool as mpool

def run(cmd):
    try:
        proc = subprocess.Popen(cmd, shell=True)
        proc.communicate()
    except:
        exit()

def run_chunk(chunk, command, flag=False):
    for file in chunk:
        cmd = eval(command + '("' + bam + ')"')
        pool.apply_async(run, args=(cmd,))
    pool.join()  # wait until all the calls to run have completed.

def main():
    chunks = [[chunk1], [chunk2]...]
    for chunk in chunks:
        run_chunk(chunk, command_1, True)
        run_chunk(chunk, command_2, True)
        run_chunk(chunk, command_3, True)

if __name__ == '__main__':
    pool = mpool.ThreadPool() 

我選擇在這里使用ThreadPool而不是常規的多處理池,因為池中的每個worker只調用subprocess.Popen ,而subprocess.Popen又生成一個新的子進程。 池中的worker只是等待該子進程完成。 因此,在自己的子流程中運行worker似乎是一種浪費。 我認為一個重量更輕的線程就可以了。

如果在實例化mpool.ThreadPool時沒有指定數字,那么您將獲得一個具有與CPU內核一樣多的工作線程的池。 這對我來說聽起來是最理想的,因為每個工作線程都會產生一個自然需要核心的子進程。 因此,有更多的工作線程(因此更多的子進程)比核心更重要,因為剩余的子進程只需要等待可用的核心。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM