← Назад к вопросам

Что такое межпроцессное взаимодействие?

2.0 Middle🔥 91 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Межпроцессное взаимодействие (IPC)

Межпроцессное взаимодействие (Inter-Process Communication, IPC) — это механизм, который позволяет двум или более независимым процессам обмениваться данными и синхронизировать свои действия. В операционной системе каждый процесс имеет собственное изолированное адресное пространство памяти, поэтому для коммуникации между ними необходимо использовать специальные механизмы, предоставляемые ОС.

Основные механизмы IPC

В Python и операционных системах существует несколько основных подходов к IPC:

1. Трубы (Pipes)

Трубы — это самый простой механизм, позволяющий одному процессу писать данные, а другому их читать. Существуют безымянные трубы (используются между родительским и дочерним процессами) и именованные трубы (FIFO).

import subprocess
import os

# Безымянная труба
process1 = subprocess.Popen(
    ["cat", "/etc/passwd"],
    stdout=subprocess.PIPE
)
process2 = subprocess.Popen(
    ["wc", "-l"],
    stdin=process1.stdout,
    stdout=subprocess.PIPE
)

output, _ = process2.communicate()
print(f"Lines: {output.decode().strip()}")

# Именованная труба (FIFO)
os.mkfifo("/tmp/my_fifo")
writer_process = subprocess.Popen(["python", "writer.py"])
reader_process = subprocess.Popen(["python", "reader.py"])

2. Сокеты (Sockets)

Сокеты — это более универсальный механизм, позволяющий процессам взаимодействовать как в пределах одной машины (Unix domain sockets), так и по сети (TCP/UDP).

import socket
import os

# Unix domain socket
socket_path = "/tmp/python_socket"

# Сервер
server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
if os.path.exists(socket_path):
    os.remove(socket_path)

server_socket.bind(socket_path)
server_socket.listen(1)

while True:
    connection, _ = server_socket.accept()
    try:
        data = connection.recv(1024)
        print(f"Received: {data.decode()}")
        connection.sendall(b"OK")
    finally:
        connection.close()

# Клиент
client_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
client_socket.connect(socket_path)
client_socket.sendall(b"Hello")
response = client_socket.recv(1024)
print(f"Response: {response.decode()}")
client_socket.close()

3. Очереди сообщений (Message Queues)

Очереди сообщений позволяют асинхронно обмениваться сообщениями между процессами. Python предоставляет модуль queue для работы с очередями в пределах одного приложения.

import multiprocessing
from queue import Queue

def producer(queue):
    for i in range(5):
        queue.put(f"Message {i}")
        print(f"Sent: Message {i}")

def consumer(queue):
    while True:
        message = queue.get()
        if message is None:
            break
        print(f"Received: {message}")
        queue.task_done()

if __name__ == "__main__":
    queue = multiprocessing.Queue()
    
    p1 = multiprocessing.Process(target=producer, args=(queue,))
    p2 = multiprocessing.Process(target=consumer, args=(queue,))
    
    p1.start()
    p2.start()
    
    p1.join()
    queue.put(None)  # Сигнал завершения
    p2.join()

4. Разделяемая память (Shared Memory)

Разделяемая память позволяет нескольким процессам обращаться к одной области памяти. Python предоставляет модуль multiprocessing.shared_memory.

import multiprocessing
from multiprocessing import shared_memory
import numpy as np

def writer():
    shm = shared_memory.SharedMemory(name="my_shm", create=True, size=100)
    buffer = np.ndarray((10,), dtype=np.int32, buffer=shm.buf)
    buffer[:] = np.arange(10)
    print(f"Wrote: {buffer}")
    shm.close()

def reader():
    import time
    time.sleep(1)  # Дождёмся создания памяти
    shm = shared_memory.SharedMemory(name="my_shm")
    buffer = np.ndarray((10,), dtype=np.int32, buffer=shm.buf)
    print(f"Read: {buffer}")
    shm.close()
    shm.unlink()  # Удаляем

if __name__ == "__main__":
    p1 = multiprocessing.Process(target=writer)
    p2 = multiprocessing.Process(target=reader)
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()

5. Сигналы (Signals)

Сигналы — это простой механизм асинхронной коммуникации для уведомления процесса о возникновении события.

import signal
import os
import time

def signal_handler(signum, frame):
    print(f"Received signal {signum}")
    exit(0)

signal.signal(signal.SIGUSR1, signal_handler)

print(f"PID: {os.getpid()}")
while True:
    print("Waiting...")
    time.sleep(1)

# В другом терминале: kill -SIGUSR1 <PID>

Сравнение механизмов

МеханизмСкоростьПростотаНадёжностьСинхронизация
ТрубыВысокаяВысокаяХорошая+/-
СокетыСредняяСредняяОтличная+/-
ОчередиСредняяСредняяОтличная+++
Разделяемая памятьОчень высокаяНизкая+/--
СигналыНизкаяСредняя+/-++

Практические рекомендации

  • Используйте очереди для асинхронной передачи сообщений между процессами
  • Сокеты подходят для сетевого взаимодействия и сложных протоколов
  • Разделяемую память применяйте только для обмена большими объёмами данных, требующих синхронизации
  • Сигналы используйте для простых уведомлений о событиях
  • Трубы идеальны для конвейеризации команд в shell-скриптах

Выбор механизма зависит от требований вашего приложения: скорости, надёжности, простоты реализации и типа данных, которые нужно передавать.

Что такое межпроцессное взаимодействие? | PrepBro