进程间内存空间是相互独立的,多个子进程并发,他们在执行代码时,是由CPU随机选取分配,当遇到较长的执行步骤,会引起步骤间的相互影响。 这个时候就需要互斥锁,它相当于给执行步骤添加了一个标签,同一时间内,有且仅有一个标签内的程序可以运行,这样就可以避免子进程执行关键步骤被相互影响的问题。
在multiprocessing模块中可以找到Lock这个功能
先执行一段不加锁的代码
from multiprocessing import Process,Lock
def task1():
for i in range(10000):
print("===")
def task2():
for i in range(10000):
print("===============")
def task3():
for i in range(10000):
print("======================================")
if __name__ == '__main__':
mutex = Lock()
p1 = Process(target=task1)
p2 = Process(target=task2)
p3 = Process(target=task3)
p1.start()
p2.start()
p3.start()
复制代码
截取了其中一段,其结果很好的说明子进程在执行时会相互抢CPU资源,这种情况如果出现在写入数据时就会造成数据的异常。
===============
===============
==================
=====================================================
===
======================================
=========================================
=====================================================
======================================
======================================
======================================
===
=====================================================
===
复制代码
我们现在给程序加上互斥锁,需要注意加的必须是同一把互斥锁,锁中间写入的是需要保证完整性的程序
lock.acquire()
lock.release()
复制代码
def task1(lock):
lock.acquire()
for i in range(10000):
print("===")
lock.release()
def task2(lock):
lock.acquire()
for i in range(10000):
print("===============")
lock.release()
def task3(lock):
lock.acquire()
for i in range(10000):
print("======================================")
lock.release()
if __name__ == '__main__':
mutex = Lock()
p1 = Process(target=task1,args=(mutex,))
p2 = Process(target=task2,args=(mutex,))
p3 = Process(target=task3,args=(mutex,))
p1.start()
p2.start()
p3.start()
复制代码
子进程的执行结果将是有序的,但是执行顺序并不是按照从上到下的顺序依次执行,子进程在启动后的执行先后完全是CPU的随机执行,不过我们程序的子进程在创建上是有一个非常小的时间差,从而导致了顺序执行,如果可以保证子进程在同一时刻创建完成,那么他们的执行将会是无序的。