2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プロセス間通信(IPC)の手段とその使い方

Posted at

はじめに

プロセス間通信(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()
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?