Python进程间的通信方式

保持多个进程之间数据的一致性至关重要,此时需要用到进程同步技术

(一)多个进程需要同时访问共享资源时,Lock可以避免访问发生冲突

from multiprocessing import Process, Lock


def func(lock, num):
    lock.acquire()
    try:
        print('hello world', num)
    finally:
        lock.release()


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

为了保证有序输出数字,每个进程操作前先将print语句上锁,操作完毕后解锁,lock对象需要通过参数传进函数中

输出:hello world 0
hello world 1
hello world 2
hello world 3
hello world 4
hello world 5
hello world 6
hello world 7
hello world 8
hello world 9 

(二)Event对象被set后发送信号给wait的进程

from multiprocessing import Process,Event
import time, random
def eating(event):
    event.wait()
    print('去吃饭的路上...')
def making(event):
    print('做饭中')
    time.sleep(random.randint(1,5))
    print('做好了,快来...')
    event.set()
if __name__ == '__main__':
    event=Event()
    t1 = Process(target=eating,args=(event,))
    t2 = Process(target=making,args=(event,))
    t1.start()
    t2.start()
#可以使用is_set()判断是否被set,以及clear()清楚set。

输出:做饭中
做好了,快来...
去吃饭的路上... 

(三)共享内存能实现进程间的数据传递,适合大量数据的场合

from multiprocessing import Process,Value,Array
def f(num,arr):
    num.value=3.1415
    for i in range(len(arr)):
        arr[i]*=2

if __name__=='__main__':
    num=Value('d',0.0)
    arr=Array('i',range(10))
    p=Process(target=f,args=(num,arr))
    p.start()
    p.join()
    print(num.value)
    print(arr[:])

输出:3.1415
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 

(四)Manager对象生成的数据允许其他进程访问

from multiprocessing import Process,Manager

def f(d,l):
    d['name']='qqq'
    d['age']='12'
    d['sex']='male'
    l.reverse()

if __name__=='__main__':
    with Manager() as manager:
        d=manager.dict()
        l=manager.list(range(10))
        p=Process(target=f,args=(d,l))
        p.start()
        p.join()
        for item in d.items():
            print(item)
        print(l)

输出:('name', 'qqq')
('age', '12')
('sex', 'male')
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 

(五)使用管道或队列进行进程间的数据交换

管道:

from multiprocessing import Process,Pipe
def f(conn):
    conn.send('hello world')
    conn.close()
if __name__=='__main__':
    parent_conn,child_conn=Pipe()
    p=Process(target=f,args=(child_conn,))
    p.start()
    p.join()
    print(parent_conn.recv())
    parent_conn.close()

输出:hello world 

队列 

import multiprocessing
def foo(q):
    q.put('hello world')

if __name__=='__main__':
    multiprocessing.set_start_method('spawn')#windows系统创建子进程的方式
    queue=multiprocessing.Queue()
    p=multiprocessing.Process(target=foo,args=(queue,))
    p.start()
    p.join()
    print(queue.get())

输出:hello world

猜你喜欢

转载自blog.csdn.net/q354636996/article/details/89477206