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

Какие знаешь способо передачи данных между процессами в Python?

2.0 Middle🔥 151 комментариев
#Асинхронность и многопоточность

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

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

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

Способы передачи данных между процессами в Python

Межпроцессная коммуникация (IPC) — критически важна для многопроцессных приложений. Python предоставляет несколько мощных инструментов для этого.

1. Queue из multiprocessing

Queue — это потокобезопасная очередь для передачи данных между процессами. Это наиболее простой и рекомендуемый способ.

from multiprocessing import Process, Queue
import time

def worker(queue):
    for i in range(3):
        queue.put(f"Message {i}")
        time.sleep(1)

def main():
    q = Queue()
    p = Process(target=worker, args=(q,))
    p.start()
    
    while True:
        try:
            data = q.get(timeout=2)
            print(f"Получено: {data}")
        except:
            break
    
    p.join()

if __name__ == '__main__':
    main()

Преимущества: простота, безопасность, поддержка различных типов данных. Недостатки: синхронная природа (блокирующие операции).

2. Pipe

Pipe — это двусторонний канал связи между двумя процессами. Меньше overhead чем Queue, но работает только с двумя процессами.

from multiprocessing import Process, Pipe

def worker(conn):
    conn.send("Hello from child")
    msg = conn.recv()
    print(f"Child получил: {msg}")
    conn.close()

def main():
    parent_conn, child_conn = Pipe()
    p = Process(target=worker, args=(child_conn,))
    p.start()
    
    msg = parent_conn.recv()
    print(f"Parent получил: {msg}")
    parent_conn.send("Hello from parent")
    
    p.join()

if __name__ == '__main__':
    main()

Преимущества: низкий overhead, скорость. Недостатки: работает только с двумя процессами.

3. Shared Memory

Shared Memory — прямой доступ к общей памяти. Самый быстрый способ, но требует тщательной синхронизации.

from multiprocessing import Process, Value, Array, Lock
import time

def worker(shared_int, shared_array, lock):
    for i in range(5):
        with lock:
            shared_int.value += 1
            shared_array[i] = i * 10
        time.sleep(0.1)

def main():
    shared_int = Value('i', 0)
    shared_array = Array('d', 5)
    lock = Lock()
    
    processes = []
    for _ in range(3):
        p = Process(target=worker, args=(shared_int, shared_array, lock))
        p.start()
        processes.append(p)
    
    for p in processes:
        p.join()
    
    print(f"Финальное значение: {shared_int.value}")

if __name__ == '__main__':
    main()

Преимущества: максимальная скорость. Недостатки: требует явной синхронизации, сложнее в отладке.

4. Manager

Manager — высокоуровневая абстракция для совместного использования данных. Позволяет использовать сложные структуры данных.

from multiprocessing import Process, Manager

def worker(shared_dict, shared_list):
    shared_dict['key'] = 'value from child'
    shared_list.append('item from child')

def main():
    with Manager() as manager:
        shared_dict = manager.dict()
        shared_list = manager.list()
        
        p = Process(target=worker, args=(shared_dict, shared_list))
        p.start()
        p.join()
        
        print(f"Словарь: {dict(shared_dict)}")

if __name__ == '__main__':
    main()

Преимущества: поддержка сложных типов, простота. Недостатки: медленнее чем Shared Memory.

5. Redis и внешние хранилища

Для распределённых систем можно использовать внешние хранилища как промежуточный слой.

import redis
from multiprocessing import Process

def worker(worker_id):
    r = redis.Redis()
    for i in range(3):
        r.lpush(f'queue:{worker_id}', f'message {i}')

def main():
    r = redis.Redis()
    processes = []
    for i in range(2):
        p = Process(target=worker, args=(i,))
        p.start()
        processes.append(p)
    
    for p in processes:
        p.join()

Преимущества: масштабируемость, независимость процессов. Недостатки: требует отдельного сервиса.

6. Файлы и файловые блокировки

Для простых случаев можно использовать файловую систему.

import json
import fcntl

def write_data(filename, data):
    with open(filename, 'w') as f:
        fcntl.flock(f.fileno(), fcntl.LOCK_EX)
        try:
            json.dump(data, f)
        finally:
            fcntl.flock(f.fileno(), fcntl.LOCK_UN)

Преимущества: простота, нет зависимостей. Недостатки: медленно, требует тщательного управления.

Рекомендации

  • Queue: начните отсюда, 90% случаев
  • Pipe: когда два процесса и нужна скорость
  • Shared Memory: только при критичных требованиях к производительности
  • Manager: для быстрого прототипирования
  • Redis: для распределённых систем и микросервисов