time.sleep - 使线程或进程休眠?

422
在*nix系统下的Python中,time.sleep()会阻塞线程还是进程?
7个回答

422

它会阻塞线程。如果你查看Python源代码中的Modules/timemodule.c文件,在调用floatsleep()时,你会发现睡眠操作的实质部分被包含在一个Py_BEGIN_ALLOW_THREADS和Py_END_ALLOW_THREADS块中,允许其他线程在当前线程睡眠时继续执行。你也可以通过一个简单的Python程序来测试:

import time
from threading import Thread

class worker(Thread):
    def run(self):
        for x in xrange(0,11):
            print x
            time.sleep(1)

class waiter(Thread):
    def run(self):
        for x in xrange(100,103):
            print x
            time.sleep(5)

def run():
    worker().start()
    waiter().start()

这将会打印:

>>> thread_test.run()
0
100
>>> 1
2
3
4
5
101
6
7
8
9
10
102

4
如何说明“线程”被阻塞了。为什么只有5和103没有被打印出来,而所有其他数字都被打印出来了。如果有人能解释一下,那对我真是太有帮助了。 - akki
@akki:请提出一个新问题,而不是在旧问题的评论中提问。此外,数字5会被打印出来(它就在101之前)。 - Nick Bastin
19
开一个新问题来问这个答案的意思?这对我来说似乎很奇怪。我原本的意思是11(不是5),抱歉现在无法更正我的评论。 实际上,我需要一些帮助理解这个答案试图表达的观点。 - akki
第一个答案:range函数xrange(k, m)返回从k到m-1的数字,包括k和m-1,因此表达式list(xrange(100, 103))返回[100, 101, 102]。这意味着length(list(xrange(k, m))) == m - k。 - Jeff Younker
第二个答案:他的观点是,当“waiter()”正在睡眠时,“worker”继续运行。 - Jeff Younker
3
具体而言,time.sleep()会阻塞调用time.sleep()的线程,但它释放Python GIL以运行其他线程(因此不会阻塞进程)。Nick的示例并没有真正展示线程的阻塞,更多地展示了GIL的释放(从而显示进程未被阻塞)。我认为,如果他在waiter()线程中的time.sleep(5)后面添加了更多内容,比如一个打印语句,就会显示直到time.sleep(5)完成后才会发生打印(即阻塞)。 - gunit

65

除非您的应用程序只有一个线程,在这种情况下,它将使该线程以及实际上整个进程睡眠,否则它只会使线程睡眠。

然而,Python文档关于sleep()并没有明确说明这一点,因此我可以理解造成的困惑!


5
@MichaelMrozek说:sleep(3)表示:“使调用线程睡眠,直到经过了seconds秒或一个未被忽略的信号到达。”并且存在Python文档错误。 - jfs

40

只需线程。


19

该线程将被阻塞,但进程仍然存在。

在单线程应用程序中,这意味着当您休眠时一切都被阻塞。在多线程应用程序中,只有您明确“休眠”的线程将会被阻塞,其他线程仍将在进程内运行。


4

除非您的进程仅有一个线程,否则只会影响该线程。


3

进程本身无法运行,它只是线程的容器。因此,在执行方面,无法暂停进程。这对进程根本不适用。


什么?这也许在Windows或其他某些系统上是正确的,但肯定不是普遍适用的。Unix传统上根本没有线程,因此Python程序运行一个进程(以某种抽象的方式具有单个线程),这就是sleep命令将会暂停的内容。 - tripleee
2
很遗憾让您失望,但在Windows和所有*nix系统中,主要运行单元是线程。您无法在没有线程的情况下运行进程。如果您退出了最后一个线程,则进程将终止。 - Denis The Menace
2
这并没有回答问题。特别是,这个问题是关于Python的。Python有一个全局解释器锁(GIL)。如果一个线程在持有GIL时进入睡眠状态,它将阻塞进程中所有的Python线程,因为它们都共享同一个锁。 - Cort Ammon

1
它会阻塞线程,如果在同一线程中执行,而不是在主代码中执行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接