python - 使用Thread和Process的不同结果

标签 python multithreading

我写了非常简单的代码:

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。

当我们在线程中执行它时,它们以某种方式分割全局变量 n,但我无法理解为什么结果总是不同......?

希望我能解释清楚,你会有所帮助..

提前谢谢您!

附注

最重要的是! 为什么不是 2 000 000?

结果应为 1 000 000 + 1 000 000 = 2 000 000

最佳答案

您的线程同时更新n,并且不一定会看到来自其他线程的更新。例如,两者完全同时更新值 1nn 的值仅增加到 2,而不是 3。这种情况发生多次。因此,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 密集型代码。 因此锁定整个循环消除了线程之间的大量切换和强制。

关于python - 使用Thread和Process的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46716388/

相关文章:

python - 尝试使用多处理来填充 python 中的数组

java - 不同线程中填充的列表在调用者线程中显示为空 - Java

java - 让当前线程 hibernate ,让其他线程唤醒它

python - python中类似向量计算的并行乘法

c - 防止多个线程只访问数组的一个元素(而不是整个数组)

python - 无法在python中获取页面源代码

python - Python 中的参数和参数如何工作?

python - 如何创建一个函数来等待 bool 值变为 true

python - 根据登录用户过滤 Django 管理控制台行

c# - 如何将 PropertyChanged 事件从订阅发送到基于 Interval 的 IObservable