我编写了非常简单的代码:
n = 0
def calculate_n(number):
global n
for i in range(number):
n += 1
print n
def print_n():
global n
print "n= "
print n
并在主要:
if __name__ == '__main__':
number = 1000000
t1 = Process(target=calculate_n, args=(number,))
t1.start()
t2 = Process(target=calculate_n, args=(number,))
t2.start()
print_n()
它给出了结果:
n = 1000000
n = 1000000
应该如此。当我将main中的代码更改为这种情况时:
number = 1000000
t1 = Thread(target=calculate_n, args=(number, ))
t1.start()
t2 = Thread(target=calculate_n, args=(number,))
t2.start()
我总是得到不同的结果:
n = 1388791
n = 1390167
n = 1426284
n = 1427452
n = 1295707
n = 1297116
等等。
所以第一种情况相当简单。当我们执行Process时,代码运行在不同的进程中,两个不同的进程使用“不同的”全局变量n,我总是得到预期的结果:1000000和1000000.
当我们在Threads中执行它时,它们以某种方式分割全局变量n,但是我无法理解为什么结果总是不同的东西......?
希望我确实解释它透明,你会帮助..
提前谢谢!
P.S。
最重要的! 为什么不是2 000 000?
结果应为1 000 000 + 1 000 000 = 2 000 000
答案 0 :(得分:2)
您的主题同时更新n
,并且不一定会看到来自其他主题的更新。例如,两者都在同一时间更新值n
的{{1}}。 1
的值3
仅增加到n
而不是2
。这种情况多次发生。因此,n
的值始终小于2000000。
您需要查看全局变量:
from threading import Thread, RLock
lock = RLock()
n = 0
def calculate_n(number):
global n
for i in range(number):
with lock:
n += 1
print n
def print_n():
global n
print "n= "
print n
if __name__ == '__main__':
number = 1000000
t1 = Thread(target=calculate_n, args=(number, ))
t1.start()
t2 = Thread(target=calculate_n, args=(number,))
t2.start()
t1.join()
t2.join()
print_n()
输出:
1991917
2000000
n=
2000000
这会减慢很多事情。锁定整个循环会使事情变得更快:
def calculate_n(number):
global n
with lock:
for i in range(number):
n += 1
print n
由于GIL线程无论如何都不会加速CPU绑定代码。 因此,锁定整个循环会消除线程之间的大量切换和强制。