Pythonでは、マルチプロセスプログラミングをサポートしていますが、複数のプロセス間でデータをやりとりする際には`Queue`と`Pipe`という二つの主要な手法があります。この記事では、これらの概念について理解を深めるため、基本的な使用方法から応用例まで詳しく解説します。
QueueとPipeとは
`Queue`と`Pipe`はマルチプロセス環境下でプロセス間のデータ通信を行うためのPythonの組み込みライブラリです。`Queue`はデータをFIFO(First-In, First-Out)方式で管理し、`Pipe`は任意のタイミングでデータを送受信できるという特徴があります。
Queueの特徴
Queueは以下のような特徴を持っています。
- FIFO(First-In, First-Out)方式でデータを管理
- データの送受信がスレッドセーフ
- ブロッキングと非ブロッキングの両方の操作が可能
Pipeの特徴
Pipeは以下のような特徴を持っています。
- 任意のタイミングでのデータ送受信が可能
- 単方向と双方向の通信が可能
- オブジェクトをそのまま送受信できる
基本的な使用方法
Queueの使用方法
Queueを使用する際の基本的なコードは以下のようになります。
from multiprocessing import Process, Queue
def worker(q):
# Queueにデータを追加
q.put('Hello from worker process.')
if __name__ == '__main__':
q = Queue()
p = Process(target=worker, args=(q,))
p.start()
p.join()
# Queueからデータを取得
print(q.get())
この例では、`worker`という名前のプロセスが`Queue`に`’Hello from worker process.’`というデータを追加しています。メインプロセスはそのデータを`q.get()`で取得しています。
Pipeの使用方法
Pipeを使用する基本的なコードは以下です。
from multiprocessing import Process, Pipe
def worker(conn):
# Pipeにデータを送信
conn.send('Hello from worker process.')
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=worker, args=(child_conn,))
p.start()
p.join()
# Pipeからデータを受信
print(parent_conn.recv())
この例では、`worker`プロセスが`Pipe`を使って`’Hello from worker process.’`というデータを送信しています。メインプロセスはそのデータを`parent_conn.recv()`で受信しています。
応用例
Queueを使った状態の共有
複数のプロセスが共通の状態やリソースを共有する必要がある場合、Queueが便利です。
from multiprocessing import Process, Queue
import time
def worker1(q):
for i in range(5):
time.sleep(1)
q.put(f'Worker1: Count {i}')
def worker2(q):
for i in range(5):
time.sleep(1)
q.put(f'Worker2: Count {i}')
if __name__ == '__main__':
q = Queue()
p1 = Process(target=worker1, args=(q,))
p2 = Process(target=worker2, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
while not q.empty():
print(q.get())
Pipeを使ったリアルタイム通信
リアルタイムでのデータのやりとりが必要な場合、Pipeが有用です。
from multiprocessing import Process, Pipe
import time
def worker1(conn):
for i in range(5):
time.sleep(1)
conn.send(f'Worker1: Count {i}')
def worker2(conn):
for i in range(5):
time.sleep(1)
conn.send(f'Worker2: Count {i}')
if __name__ == '__main__':
conn1, conn2 = Pipe()
p1 = Process(target=worker1, args=(conn1,))
p2 = Process(target=worker2, args=(conn2,))
p1.start()
p2.start()
p1.join()
p2.join()
while conn1.poll():
print(conn1.recv())
while conn2.poll():
print(conn2.recv())
まとめ
Pythonでのマルチプロセス環境下でのデータ通信は、`Queue`と`Pipe`を使って比較的簡単に実現できます。QueueはFIFO方式で安全なデータ通信が可能で、Pipeはリアルタイム性が高いです。用途に応じて適切な方法を選ぶことが重要です。
コメント