【发布时间】:2019-07-27 15:34:46
【问题描述】:
有人能解释一下 Python 线程是如何工作的吗? thread.start() 在切换回另一个上下文(如下面的 main)之前是否没有运行目标函数完成?
import time
import threading
def threadfunc():
# time.sleep(1)
print('thread print 1', flush=True)
print('thread print 2', flush=True)
#time.sleep(1)
print('before thread', flush=True)
thread1 = threading.Thread(target=threadfunc)
thread1.start()
print('after thread', flush=True)
输出:
before thread
thread print 1
after thread
thread print 2 #shouldn't this be after "print 1"?
【问题讨论】:
-
如果
thread.start()会等待线程完成,那么使用线程的意义何在? -
在国内。不应在“print1”之后打印。您正在一个独立的线程中运行该函数。所以代码将继续执行。这就是我们使用线程的原因,所以代码执行不会等到函数完成,否则在第一种情况下线程的意义何在
-
你们俩都没有解释 Python 代码是如何确定执行的。线程仍然被 GIL 阻塞,所以通常你会期望 python 代码在切换出上下文之前完成。线程必须切换到非运行状态,例如使用睡眠功能或执行一些 IO。是因为 print() 被认为是一个输出函数,然后使线程切换上下文?
-
Re,“……是因为 print() 是……输出函数吗?”可能是。我不知道 C Python 的内部原理,但我会假设对操作系统的任何调用都可能是一个让步点,并且我会假设任何可能阻塞 I/O 的系统调用肯定必须 i> 成为屈服点。如果这不是真的,并且如果您不能使用线程进行多处理(由于 GIL,您不能这样做),那么实际上就没有使用线程的理由了。
-
C Python 线程不必在运行的整个过程中保持 GIL 持续锁定。它只需要在访问可能与其他线程共享的数据结构(例如,任何 Python 对象)时锁定它。原则上,它可以在每两个原始语句之间解锁、屈服,然后再次锁定。我不知道这是否是它实际上所做的,但我确信(由于我上面给出的原因)它必须在每次可能阻塞的系统调用之前解锁 GIL。
标签: python python-3.x multithreading python-multithreading