在 Python 3 中,实现多进程间通信的方式有以下几种常见方式:

  1. 队列(Queue)
    使用 multiprocessing.Queue 类可以在多个进程之间安全地传递消息和数据。多个进程可以将数据放入队列中,然后其他进程可以从队列中获取这些数据。
  2. 管道(Pipe)
    使用 multiprocessing.Pipe 类可以创建一对连接的管道,允许两个进程之间进行双向通信。一个进程可以向管道写入数据,另一个进程则可以从管道中读取这些数据。
  3. 共享内存(Shared Memory)
    可以使用 multiprocessing.Arraymultiprocessing.Value 来创建共享内存,允许多个进程访问相同的内存区域。这样可以在进程之间共享数据,但需要注意处理数据同步和互斥访问的问题。
  4. 管理器(Manager)
    通过 multiprocessing.Manager 类可以创建一个管理器对象,该对象提供了许多共享数据结构,如列表、字典等,可以被多个进程访问和修改。
  5. 信号量(Semaphore)
    使用 multiprocessing.Semaphore 可以控制多个进程对共享资源的访问,通过信号量可以限制同时访问共享资源的进程数量。
  6. 事件(Event)
    通过 multiprocessing.Event 可以实现进程间的事件通知机制,一个进程可以设置事件为触发状态,另一个进程可以等待事件的触发。

文章目录

  • 1. 队列(Queue)
  • 2. 管道(Pipe)
  • 3. 共享内存(Shared Memory)
  • 4. 管理器(Manager)
  • 5. 信号量(Semaphore)
  • 6. 事件(Event)

1. 队列(Queue)

from multiprocessing import Process, Queue

def producer(q):
    for i in range(5):
        q.put(i)

def consumer(q):
    while not q.empty():
        print(q.get())

if __name__ == '__main':
    q = Queue()
    p = Process(target=producer, args=(q,))
    c = Process(target=consumer, args=(q,))
    
    p.start()
    c.start()
    
    p.join()
    c.join()

2. 管道(Pipe)

from multiprocessing import Process, Pipe

def parent(conn):
    # 父进程不断地发送数据到子进程
    count = 0
    while True:
        data_to_send = f"Data {count}"
        conn.send(data_to_send)
        count += 1

def child(conn):
    # 子进程接收父进程发送的数据
    while True:
        received_data = conn.recv()
        print("Child received:", received_data)

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()

    parent_process = Process(target=parent, args=(parent_conn,))
    child_process = Process(target=child, args=(child_conn,))

    parent_process.start()
    child_process.start()

    parent_process.join()
    child_process.join()

3. 共享内存(Shared Memory)

from multiprocessing import Process, Value, Array

def modify_data(val, arr):
    val.value += 10
    for i in range(len(arr)):
        arr[i] *= 2

if __name__ == '__main__':
    v = Value('i', 5)  # integer value
    a = Array('i', [1, 2, 3, 4, 5])  # array of integers
    
    p = Process(target=modify_data, args=(v, a))
    p.start()
    p.join()
    
    print(v.value)  # Output: 15
    print(a[:])     # Output: [2, 4, 6, 8, 10]

4. 管理器(Manager)

multiprocessing.Manager 提供的数据结构是进程间安全的。Manager 类提供了一种在多个进程之间共享和管理数据的方式。通过 Manager 创建的数据结构,例如列表、字典等,可以被多个进程同时访问和修改,而不需要显式地进行数据同步或互斥操作。

Manager 类使用了底层的进程锁和进程间通信机制来保证数据的一致性和安全性。当多个进程尝试同时修改 Manager 创建的共享数据结构时,内部会使用锁机制来实现互斥访问,确保每个进程的操作能够按序执行,避免出现竞态条件或不一致的情况

from multiprocessing import Process, Manager

def modify_list(lst):
    lst.append(4)
    lst.append(5)

if __name__ == '__main__':
    with Manager() as manager:
        shared_list = manager.list([1, 2, 3])
        
        p = Process(target=modify_list, args=(shared_list,))
        p.start()
        p.join()
        
        print(shared_list)  # Output: [1, 2, 3, 4, 5]

5. 信号量(Semaphore)

from multiprocessing import Process, Semaphore

def access_shared_resource(sem, resource):
    sem.acquire()
    try:
        resource.value -= 1
    finally:
        sem.release()

if __name__ == '__main__':
    s = Semaphore(value=1)
    shared_resource = Value('i', 10)
    
    p1 = Process(target=access_shared_resource, args=(s, shared_resource))
    p2 = Process(target=access_shared_resource, args=(s, shared_resource))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()
    
    print(shared_resource.value)  # Output: 8

6. 事件(Event)

from multiprocessing import Process, Event

def wait_for_event(e):
    print("Waiting for event to be set...")
    e.wait()
    print("Event is set!")

def set_event(e):
    print("Event will be set in 3 seconds")
    time.sleep(3)
    e.set()

if __name__ == '__main__':
    evt = Event()
    
    p1 = Process(target=wait_for_event, args=(evt,))
    p2 = Process(target=set_event, args=(evt,))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()