【问题标题】:How NOT to wait for a thread to finish in Python如何在 Python 中不等待线程完成
【发布时间】:2018-06-25 06:28:37
【问题描述】:
在这个question 中,他实际上问了我想要什么。除了答案是删除括号。但是,如果我删除括号,那么我将无法为我的函数传递参数。
如何在不等待的情况下完成以下简单代码:
from time import sleep
import threading
def whatever(i):
sleep(5)
print("Hey! It's me number " + str(i))
for i in range(3):
t = threading.Thread(target=whatever(i))
t.start()
期望的输出是
Hey! It's me number 0
Hey! It's me number 1
Hey! It's me number 2
全部同时打印
【问题讨论】:
标签:
python
multithreading
python-3.x
python-multithreading
【解决方案1】:
From the documentation, target 应该是可调用的:
target 是 run() 方法调用的可调用对象
您不是将函数传递给target,而是传递函数的返回值,因此函数在传递给threading.Thread 时立即运行,而不是在您调用t.start() 时运行。
您应该使用args 参数来为您的可调用对象指定参数。
只需更改此行:
t = threading.Thread(target=whatever(i))
到
t = threading.Thread(target=whatever, args=(i,))
【解决方案2】:
您似乎没有意识到这一行的作用:t = threading.Thread(target=whatever(i)),删除括号不仅仅是不等待线程完成它,因此您实际上可以在单独的线程中启动函数:
target 应该是函数对象本身,但是当您执行 t = threading.Thread(target=whatever(1)) 时,target 将是您已经在原始线程中运行的 whatever 的返回值,您需要给出 threading然后函数本身单独指定参数,它会像这样为你调用它:
from time import sleep
import threading
def whatever(i):
sleep(5)
print("Hey! It's me number " + str(i))
for i in range(3):
t = threading.Thread(target=whatever, args=(i,))
t.start()
【解决方案3】:
from time import sleep
import threading
def whatever(i):
print("Hey! It's me number " + str(i))
for i in range(3):
t = threading.Thread(target=whatever, args=(i,))
t.start()
你必须考虑一件事。
在 Python 中,我们有一个叫做 GIL 的东西——全局解释器锁。简而言之,它可以让你的 python 应用程序的一个线程同时在给定的解释器中执行。什么意思?
在 Python 中实现真正的并发并不那么容易——虽然由于我们今天拥有超快的 CPU,指令看起来是同时执行的,但实际上并非如此。
【解决方案4】:
只需将其包装成 lambda。
from time import sleep
import threading
def whatever(i):
sleep(5)
print("Hey! It's me number " + str(i))
for i in range(3):
t = threading.Thread(target=lambda: whatever(i))
t.start()