子プロセスでのリソースアクセスを制限したい。たとえば、-limit http downloads、disk ioなどです。この基本コードを拡張してどのように実現できますか?
基本的なコード例をいくつか教えてください。
pool = multiprocessing.Pool(multiprocessing.cpu_count())
while job_queue.is_jobs_for_processing():
for job in job_queue.pull_jobs_for_processing:
pool.apply_async(do_job, callback = callback)
pool.close()
pool.join()
すべての子プロセスでグローバルを定義するために、プールを作成するときに、initializerおよびinitargs引数を使用します。
例えば:
from multiprocessing import Pool, Lock
from time import sleep
def do_job(i):
"The greater i is, the shorter the function waits before returning."
with lock:
sleep(1-(i/10.))
return i
def init_child(lock_):
global lock
lock = lock_
def main():
lock = Lock()
poolsize = 4
with Pool(poolsize, initializer=init_child, initargs=(lock,)) as pool:
results = pool.imap_unordered(do_job, range(poolsize))
print(list(results))
if __name__ == "__main__":
main()
このコードは、ロックを使用しているため、0〜3の数字を昇順(ジョブが送信された順序)で出力します。 with lock:
行をコメントアウトして、番号が降順で出力されることを確認します。
このソリューションは、WindowsとUNIXの両方で機能します。ただし、プロセスはunixシステムでフォークできるため、unixはモジュールスコープでグローバル変数を宣言するだけで済みます。子プロセスは、親のメモリのコピーを取得します。これには、引き続き機能するロックオブジェクトが含まれます。したがって、初期化子は厳密には必要ありませんが、コードがどのように機能するかを文書化するのに役立ちます。マルチプロセッシングがフォークによってプロセスを作成できる場合、以下も機能します。
from multiprocessing import Pool, Lock
from time import sleep
lock = Lock()
def do_job(i):
"The greater i is, the shorter the function waits before returning."
with lock:
sleep(1-(i/10.))
return i
def main():
poolsize = 4
with Pool(poolsize) as pool:
results = pool.imap_unordered(do_job, range(poolsize))
print(list(results))
if __name__ == "__main__":
main()
グローバルセマフォを使用して、リソースにアクセスしている場合はそれを取得します。例えば:
import multiprocessing
from time import sleep
semaphore = multiprocessing.Semaphore(2)
def do_job(id):
with semaphore:
sleep(1)
print("Finished job")
def main():
pool = multiprocessing.Pool(6)
for job_id in range(6):
print("Starting job")
pool.apply_async(do_job, [job_id])
pool.close()
pool.join()
if __name__ == "__main__":
main()
他のスレッドがセマフォを待機しているため、このプログラムは毎秒2つのジョブのみを終了します。