保持多个进程之间数据的一致性至关重要,此时需要用到进程同步技术
(一)多个进程需要同时访问共享资源时,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