上限数を決めて協調しない外部プログラムを動かす

元はこっちがきっかけで、大量のHTMLファイルをレンダリングして画像化しようと思って「CrenaHtml2jpg」を使ったのだけど、1個ずつ動かしていくと毎秒1枚程度しか処理できなかったので複数個同時に動かしたかった。
Pythonでおそらく一番簡単な外部コマンドを起動する方法は次のsystem関数だろうけど、そのプログラムが終了するまで処理が戻らない。

import os
cmd = "notepad"
os.system(cmd)

でPopenを使うと外部プログラムを良い感じに制御しつつ、メインのプログラムを並行して動かすことが出来る。ちなみにCore2DuoでCrenaHtml2jpgを同時に最大10個起動できる状態で動かしたら約10枚/1秒になった。

from subprocess import Popen
import time

def main():
  proc_pool = []
  proc_num = 10

  for i in range(100):
    while len(proc_pool) >= proc_num:
      proc_pool = [proc for proc in proc_pool if proc.pool() == None]
      time.sleep(0.01)
    cmd = "echo hoge > proc/test%d.txt" % i
    print cmd
    proc = Popen(cmd, shell=True)
    proc_pool.append(proc)

if __name__ == '__main__':
  main()