PythonでQueueとPipeを使ってマルチプロセスのデータ交換を実現する方法

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はリアルタイム性が高いです。用途に応じて適切な方法を選ぶことが重要です。

コメント

コメントする

目次