はじめに
プロセス間通信(Inter-Process Communication、IPC)は、複数のプロセスが情報を交換するためのメカニズム。IPCは、異なるプロセスがメモリ空間を共有せずにデータをやり取りするための手段を提供する。
1. パイプ(Pipes)
名前なしパイプ(Unnamed Pipes)
名前なしパイプは、親プロセスと子プロセス間でデータを一方向に通信するために使用される。
import os
r, w = os.pipe() # パイプの作成
pid = os.fork() # プロセスの分岐
if pid > 0: # 親プロセス
os.close(r) # 読み取り側を閉じる
w = os.fdopen(w, 'w')
w.write("Hello from parent process")
w.close()
else: # 子プロセス
os.close(w) # 書き込み側を閉じる
r = os.fdopen(r)
print("Child process received:", r.read())
r.close()
名前付きパイプ(Named Pipes、FIFO)
名前付きパイプは、異なるプロセス間でデータを一方向に通信するために使用される。
import os
import time
fifo = 'myfifo'
# 名前付きパイプの作成
if not os.path.exists(fifo):
os.mkfifo(fifo)
pid = os.fork()
if pid > 0: # 親プロセス
with open(fifo, 'w') as f:
f.write("Hello from parent process")
else: # 子プロセス
time.sleep(1) # 親プロセスが書き込むまで待機
with open(fifo, 'r') as f:
print("Child process received:", f.read())
2. メッセージキュー(Message Queues)
メッセージキューは、複数のプロセス間でデータを送受信するためのキュー。
import sysv_ipc
key = 1234 # メッセージキューキー
mq = sysv_ipc.MessageQueue(key, sysv_ipc.IPC_CREAT)
pid = os.fork()
if pid > 0: # 親プロセス
mq.send(b"Hello from parent process")
else: # 子プロセス
message, _ = mq.receive()
print("Child process received:", message.decode())
3. 共有メモリ(Shared Memory)
共有メモリは、複数のプロセスが直接メモリを共有するための手段。
import sysv_ipc
key = 5678 # 共有メモリキー
memory = sysv_ipc.SharedMemory(key, sysv_ipc.IPC_CREAT, size=1024)
pid = os.fork()
if pid > 0: # 親プロセス
memory.write(b"Hello from parent process")
else: # 子プロセス
time.sleep(1) # 親プロセスが書き込むまで待機
print("Child process received:", memory.read().decode().strip())
4. ソケット(Sockets)
ソケットは、ネットワーク通信だけでなく、同じホスト内のプロセス間通信にも使用できる。
import socket
server_address = './uds_socket'
# サーバー
if os.fork() == 0:
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as server:
server.bind(server_address)
server.listen(1)
connection, _ = server.accept()
with connection:
print("Server received:", connection.recv(1024).decode())
else: # クライアント
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
time.sleep(1) # サーバーが準備できるまで待機
client.connect(server_address)
client.sendall(b"Hello from client")
5. 信号(Signals)
信号は、プロセス間で簡単な通知を行うための手段。
import signal
import os
import time
def handler(signum, frame):
print("Signal received:", signum)
signal.signal(signal.SIGUSR1, handler)
pid = os.fork()
if pid > 0: # 親プロセス
time.sleep(1)
os.kill(pid, signal.SIGUSR1)
else: # 子プロセス
time.sleep(2)
6. セマフォ(Semaphores)
セマフォは、複数のプロセス間でリソースのアクセス制御を行うための手段。
import sysv_ipc
import os
key = 9876 # セマフォキー
sem = sysv_ipc.Semaphore(key, sysv_ipc.IPC_CREAT, initial_value=1)
pid = os.fork()
if pid > 0: # 親プロセス
sem.acquire()
print("Parent process entering critical section")
time.sleep(2)
print("Parent process leaving critical section")
sem.release()
else: # 子プロセス
sem.acquire()
print("Child process entering critical section")
time.sleep(2)
print("Child process leaving critical section")
sem.release()