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
库,但需要更多的工作和关注。我开始意识到 threading
和 multiprocessing
之间的鸿沟是一件好事和有用的事情。 threading
中的线程都可以访问同一个完整的命名空间,只要注意竞争条件,它们就在同一个宇宙中运行。
另一方面,multiprocessing
中的线程(我应该在这里使用术语进程)在子进程启动后被不同名称空间的鸿沟分隔开。在它们之间传输信息时,必须使用专门的通信队列和共享命名空间对象。这将很快需要数百行样板代码。
最近开始学习线程,想在下面的代码中实现。
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
库,但需要更多的工作和关注。我开始意识到 threading
和 multiprocessing
之间的鸿沟是一件好事和有用的事情。 threading
中的线程都可以访问同一个完整的命名空间,只要注意竞争条件,它们就在同一个宇宙中运行。
另一方面,multiprocessing
中的线程(我应该在这里使用术语进程)在子进程启动后被不同名称空间的鸿沟分隔开。在它们之间传输信息时,必须使用专门的通信队列和共享命名空间对象。这将很快需要数百行样板代码。