这里说一下多进程加锁后,程序是怎么样执行的。
多进程主要是充分利用多 CPU
。那么,如果,多个进程修改同一个变量,那么,势必会对这个变量加锁,加锁后,执行顺序会是怎么样?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import osimport time from multiprocessing import Process, Value def job(v): with v.get_lock(): for i in range(10 ): time .sleep(0.1 ) v.value += i print(f"{os.getpid()} {v.value}") if __name__ == '__main__' : v = Value ("i", 0 ) p1 = Process(target=job, args=(v,)) p2 = Process(target=job, args=(v,)) p1.start () p2.start () p1.join () p2.join ()
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 87808 0 87808 1 87808 3 87808 6 87808 10 87808 15 87808 21 87808 28 87808 36 87808 45 87809 45 87809 46 87809 48 87809 51 87809 55 87809 60 87809 66 87809 73 87809 81 87809 90
很明显上述加锁方式,让多进程成为串行数据。
那么,怎么优化呢?
假设 time.sleep
是一种 CPU
密集的活动,那么,我们是不是只需要对数据的存储进行加密,不就好了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import copy import osimport time from multiprocessing import Process, Value def job(v): for i in range(10 ): tmp = 0 with v.get_lock(): tmp = copy .copy (v.value ) time .sleep(0.1 ) tmp += i with v.get_lock(): v.value = tmp print(f"{os.getpid()} {v.value}") if __name__ == '__main__' : v = Value ("i", 0 ) p1 = Process(target=job, args=(v,)) p2 = Process(target=job, args=(v,)) p1.start () p2.start () p1.join () p2.join ()
最后的输出
87135 45
也就是 v.value
是 45
,这个和正确的数值 90
有出入。