python如何正确使用多线程?

How to use multi-threading correctly in python?

最近开始学习线程,想在下面的代码中实现。

import timeit
start = timeit.default_timer()
def func(num):
    s = [(i, j, k) for i in range(num) for j in range(num) for k in range(num)]
    return s
z = 150
a,b = func(z),func(z)
print(a[:5], b[:5])
stop = timeit.default_timer()
print("time: ", stop - start)

花费的时间是:

time:  3.7628489000000003

所以我尝试使用线程模块并将代码修改为:

import timeit
from threading import Thread
start = timeit.default_timer()


def func(num):
    s = [(i, j, k) for i in range(num) for j in range(num) for k in range(num)]
    print(s[:5])

a = Thread(target=func, args=(150,))
b = Thread(target=func, args=(150,))
a.start()
b.start()
a.join()
b.join()
stop = timeit.default_timer()
print("time: ", stop - start)

花费的时间是:

time:  4.2522736

但是,它应该减半而不是增加。我的实现有什么问题吗? 请解释哪里出了问题,或者有更好的方法来实现这一点。

你遇到了所谓的全局解释器锁,简称GIL。

python中的线程不是"real"线程,也就是说它们不是同时执行,而是其中的原子操作是按照某种顺序依次计算的(这个顺序往往很难预先确定)

这意味着当您需要同时等待许多阻塞事物时,threading 库的线程很有用。这通常是在一个线程位于 receive() 方法时监听网络连接,直到收到某些东西。 其他线程可以继续做其他事情,而不必一直检查连接。 然而,threading

无法实现真正​​的性能提升

还有另一个名为 multiprocessing 的库,它确实实现了实际同时执行的真实线程。使用 multiprocessing 在许多方面类似于 threading 库,但需要更多的工作和关注。我开始意识到 threadingmultiprocessing 之间的鸿沟是一件好事和有用的事情。 threading 中的线程都可以访问同一个完整的命名空间,只要注意竞争条件,它们就在同一个宇宙中运行。

另一方面,multiprocessing中的线程(我应该在这里使用术语进程)在子进程启动后被不同名称空间的鸿沟分隔开。在它们之间传输信息时,必须使用专门的通信队列和共享命名空间对象。这将很快需要数百行样板代码。