02-进程通信

进程通信有两种方式,分别是队列和管道

队列通信

import time
from multiprocessing import Process, Queue


def func(q):
    time.sleep(1)
    q.put([1, 'yaowy', 28])


if __name__ == '__main__':
    q = Queue()
    p = Process(target=func, args=(q,))
    p.start()

    print(q.get())
    print(q.get())


Queue.get() 会阻塞。

管道通信

import time
from multiprocessing import Process, Pipe


def func(pipe):
    time.sleep(1)
    pipe.send([1, 'yaowy', 28])


if __name__ == '__main__':
    pipel, piper = Pipe()
    p = Process(target=func, args=(pipel,))
    p.start()

    print(piper.recv())
    print(piper.recv())

Pipe.recv 也会形成阻塞效果。Pipe 是双向的,会返回两个对象,表示管道的两端,recv 方法和 send 方法是相互的。

进程同步

import time
from multiprocessing import Process, Lock

def func(l: Lock, i):
    l.acquire()
    try:
        print('-'*10, i)
        time.sleep(1)
    finally:
        print('+'*10, i)
        l.release()


if __name__ == '__main__':
    lock = Lock()
    for num in range(5):
        Process(target=func, args=(lock, num)).start()

进程同步和线程同步一样使用方便。

进程中共享状态

共享内存

from multiprocessing import Process, Value, Array


def func(v: Value, a: Array):
    v.value = 3.1415926
    for i in range(len(a)):
        a[i] = -a[i]


if __name__ == '__main__':
    v = Value('d', 0.0)
    a = Array('i', range(10))

    p = Process(target=func, args=(v, a))
    p.start()
    p.join()

    print(v.value)
    print(a[:])

p.join() 是必须的,它会让主进程等待子进程执行完。

不过这个方法共享内存并不是最方便的

服务进程

由 Manager() 返回的管理器对象控制一个服务进程,该进程保存Python对象并允许其他进程使用代理操作它们。

Manager() 返回的管理器支持类型: list 、 dict 、 Namespace 、 Lock 、 RLock 、 Semaphore 、 BoundedSemaphore 、 Condition 、 Event 、 Barrier 、 Queue 、 Value 和 Array 。

from multiprocessing import Process, Manager


def func(d, l):
    d['name'] = 'yaowy'
    d['age'] = 18
    d['sex'] = 'M'
    l.reverse()


if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p = Process(target=func, args=(d, l))
        p.start()
        p.join()

        print(d)
        print(l)

使用服务进程的管理器比使用共享内存对象更灵活,因为它们可以支持任意对象类型。

posted @   yaowy  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示