Pythonプロセス
Pythonは2.6でマルチプロセスのメカニズムを導入し、豊富なコンポーネントとapiを提供し、同時アプリケーションの作成を容易にした.MultiprocessingパッケージのコンポーネントProcess,Queue,Pipe,Lockなどのコンポーネントはマルチスレッドと同様の機能を提供する.これらのコンポーネントを使用すると、マルチプロセスコンカレントプログラムを簡単に作成できます.
マルチプロセスインスタンス:
プロセスをインスタンス化するにはtargetとargsを指定する必要があります.targetは新しいプロセスのエントリメソッドでありmainメソッドと考えられる.argsはこの方法のパラメータリストです.起動プロセスはThreadを起動するのと同じで、startメソッドを呼び出す必要があります.プロセスを継承し、runメソッドを上書きし、runメソッドでプロセスの論理を実現することもできます.joinメソッドを呼び出すと、呼び出されたプロセスの実行が終了するまで、現在の呼び出しプロセスがブロックされます.
プロセスを手動で終了するとterminateメソッドが呼び出され、UNIXシステムではSIGTERM信号量が送信され、windowsシステムではTerminateProcessメソッドが使用されます.注意すべきは、exit処理ロジックは実行されず、プロセスのサブプロセスは終了されず、孤児プロセスになるだけである.
プロセス間通信
Queue
Queueはマルチプロセスの安全なキューであり,Queueを用いてマルチプロセス間のデータ転送を実現できる.putメソッドはキューにデータを挿入するために使用され、putメソッドにはblockedとtimeoutの2つのオプションパラメータがあります.blockedがTrue(デフォルト)であり、timeoutが正の場合、このメソッドは、キューに残りのスペースがあるまでtimeoutが指定した時間をブロックします.タイムアウトするとQueueが投げ出されます.Full異常.blockedがFalseであるが、Queueが満タンであると、すぐにQueueが投げ出される.Full異常.
getメソッドは、キューから要素を読み出して削除できます.同様にgetメソッドには、blockedとtimeoutの2つのオプションパラメータがあります.blockedがTrue(デフォルト)、timeoutが正の場合、待ち時間内に要素が取り込まれず、Queueが放出する.Empty異常.blockedがFalseである場合には2つのケースがあり、Queueに1つの値が利用可能である場合は直ちにその値を返す、そうでない場合はキューが空である場合は直ちにQueueを投げ出す.Empty異常.Queueのサンプルコード:
Pipes
Pipeメソッドは、1つのパイプの2つの端を表す(conn 1,conn 2)を返します.Pipeメソッドにはduplexパラメータがあり、duplexパラメータがTrue(デフォルト)の場合、このパイプはフルデュプレクスモード、すなわちconn 1とconn 2が送受信可能である.duplexはFalseであり,conn 1はメッセージの受信のみを担当し,conn 2はメッセージの送信のみを担当する.
sendメソッドとrecvメソッドは、それぞれメッセージを送信および受信する方法である.例えば、conn 1は、フルデュプレクスモードで呼び出すことができる.send送信メッセージconn 1.recvメッセージを受信します.メッセージが受信できない場合、recvメソッドはブロックされます.パイプが閉じられている場合、recvメソッドはEOFErrorを放出します.
Managers
プロセス同期
Multiprocessingパッケージには、Condition、Event、Lock、RLock、Semaphoreなどのコンポーネントが同期に使用できます.ロックを使用する例を次に示します.
プロセスプール
プロセスプール内でプロセスシーケンスを維持し、使用するとプロセスプールにプロセスを取得します.プロセスプールシーケンスに使用可能なプロセスがない場合、プロセスプールに使用可能なプロセスがあるまでプログラムは待機します.
プロセスプールには、次の2つの方法があります. apply apply_async
マルチプロセスインスタンス:
import os
from multiprocessing import Process
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid())
print('process id:', os.getpid())
print("
")
def f(name):
info('\033[31;1mfunction f\033[0m')
print('hello', name)
if __name__ == '__main__':
info('\033[32;1mmain process line\033[0m')
p = Process(target=info, args=('bob',))
p.start()
p.join()
プロセスをインスタンス化するにはtargetとargsを指定する必要があります.targetは新しいプロセスのエントリメソッドでありmainメソッドと考えられる.argsはこの方法のパラメータリストです.起動プロセスはThreadを起動するのと同じで、startメソッドを呼び出す必要があります.プロセスを継承し、runメソッドを上書きし、runメソッドでプロセスの論理を実現することもできます.joinメソッドを呼び出すと、呼び出されたプロセスの実行が終了するまで、現在の呼び出しプロセスがブロックされます.
プロセスを手動で終了するとterminateメソッドが呼び出され、UNIXシステムではSIGTERM信号量が送信され、windowsシステムではTerminateProcessメソッドが使用されます.注意すべきは、exit処理ロジックは実行されず、プロセスのサブプロセスは終了されず、孤児プロセスになるだけである.
プロセス間通信
Queue
Queueはマルチプロセスの安全なキューであり,Queueを用いてマルチプロセス間のデータ転送を実現できる.putメソッドはキューにデータを挿入するために使用され、putメソッドにはblockedとtimeoutの2つのオプションパラメータがあります.blockedがTrue(デフォルト)であり、timeoutが正の場合、このメソッドは、キューに残りのスペースがあるまでtimeoutが指定した時間をブロックします.タイムアウトするとQueueが投げ出されます.Full異常.blockedがFalseであるが、Queueが満タンであると、すぐにQueueが投げ出される.Full異常.
getメソッドは、キューから要素を読み出して削除できます.同様にgetメソッドには、blockedとtimeoutの2つのオプションパラメータがあります.blockedがTrue(デフォルト)、timeoutが正の場合、待ち時間内に要素が取り込まれず、Queueが放出する.Empty異常.blockedがFalseである場合には2つのケースがあり、Queueに1つの値が利用可能である場合は直ちにその値を返す、そうでない場合はキューが空である場合は直ちにQueueを投げ出す.Empty異常.Queueのサンプルコード:
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p2 = Process(target=f, args=(q,))
p.start()
p2.start()
print('data1:',q.get()) # prints "[42, None, 'hello']"
print('data2:',q.get())
p.join()
Pipes
Pipeメソッドは、1つのパイプの2つの端を表す(conn 1,conn 2)を返します.Pipeメソッドにはduplexパラメータがあり、duplexパラメータがTrue(デフォルト)の場合、このパイプはフルデュプレクスモード、すなわちconn 1とconn 2が送受信可能である.duplexはFalseであり,conn 1はメッセージの受信のみを担当し,conn 2はメッセージの送信のみを担当する.
sendメソッドとrecvメソッドは、それぞれメッセージを送信および受信する方法である.例えば、conn 1は、フルデュプレクスモードで呼び出すことができる.send送信メッセージconn 1.recvメッセージを受信します.メッセージが受信できない場合、recvメソッドはブロックされます.パイプが閉じられている場合、recvメソッドはEOFErrorを放出します.
from multiprocessing import Process, Pipe
def send(conn):
conn.send("Hello World")
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=send, args=(child_conn,))
p.start()
print(parent_conn.recv())
Managers
from multiprocessing import Process, Manager
def f(d, l):
d[1] = '1'
d['2'] = 2
d[0.25] = None
l.append('a')
print(l)
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
l = manager.list(range(5))
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l))
p.start()
p_list.append(p)
for res in p_list:
res.join()
print(d)
print(l)
プロセス同期
Multiprocessingパッケージには、Condition、Event、Lock、RLock、Semaphoreなどのコンポーネントが同期に使用できます.ロックを使用する例を次に示します.
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
プロセスプール
プロセスプール内でプロセスシーケンスを維持し、使用するとプロセスプールにプロセスを取得します.プロセスプールシーケンスに使用可能なプロセスがない場合、プロセスプールに使用可能なプロセスがあるまでプログラムは待機します.
プロセスプールには、次の2つの方法があります.
from multiprocessing import Process,Pool,freeze_support
import time
def Foo(i):
time.sleep(2)
return i+100
def Bar(arg):
print('-->exec done:',arg)
if __name__ == '__main__':
freeze_support()
pool = Pool(3)
for i in range(10):
pool.apply_async(func=Foo, args=(i,),callback=Bar) #
#pool.apply(func=Foo, args=(i,)) #
print('end')
pool.close()
pool.join() # , , 。