2016-03-28 53 views
2

我只是想明白,如果当我调用time.sleep(x)时,运行代码的当前线程会延迟x秒。但是,这是否释放了处理器的这些x秒或者线程是否将资源保留给自己,并且在x秒后它才开始执行下一行代码。time.sleep()函数

与我对着确切的情况编辑:

这里的情况跟我说:

class SomeHandler(tornado.websocket.WebSocketHandler) 
    @tornado.gen.coroutine 
    def something_async(): 
    time.sleep(5) 
    return result 

    def on_message(message): 
    future = yield something_async(message) 

if __name__ == '__main__': 
    application = tornado.web.Application([ 
    (r'/', SomeHandler), 
    ]) 

    http_server = tornado.httpserver.HTTPServer(application) 
    http_server.listen(8888) 
    tornado.ioloop.IOLoop.instance().start() 

现在,因为这场龙卷风将是一个单线程的服务器,究竟做time.sleep(5)在这种情况下(它会阻塞线程5秒使整个进程同步)还是协程会产生一个新的线程?

+2

对CPU进行处理并阻止任何其他线程执行有意义吗?有没有可能找到一种方法? –

+3

也许这可以帮助你:http://stackoverflow.com/questions/92928/time-sleep-sleeps-thread-or-process – Querenker

+0

简单的答案是,它将释放处理器,但实现可能会有所不同。有一种称为*旋转锁定的功能*,如果等待时间很短,线程将保留CPU。可以想象,一个实现可以使用自旋锁来实现短暂的睡眠时间,特别是在专门为此提供API的Windows上。另见http://stackoverflow.com/questions/7273474/behavior-of-pythons-time-sleep0-under-linux-does-it-cause-a-context-switch和http://stackoverflow.com/questions/ 22115831/how-to-resolve-spinlock-issues-with-multithreaded-python – cdarke

回答

3

一个例子是总是最好的:

#!/usr/bin/env python 
# -*- coding: utf-8; py-indent-offset:4 -*- 
############################################################################### 
from __future__ import (absolute_import, division, print_function) 
#      unicode_literals) 

import threading 
import time 


def func1(): 
    time.sleep(10) 
    print('Func1: Out of sleep and returning') 


def func2(flag): 
    while not flag: 
     time.sleep(1) 
     print('Func2: looping') 

    print('Func2: Flag set, leaving') 


t1 = threading.Thread(target=func1) 
f = list() 

t2 = threading.Thread(target=func2, kwargs=dict(flag=f)) 

t1.start() 
t2.start() 

t1.join() 
f.append(None) 

随着输出:

Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func1: Out of sleep and returning 
Func2: looping 
Func2: Flag set, leaving 

应当从即使t1(所述第一线程)被阻止的长time.sleep输出明显10秒,第二个线程t2正在运行。

甚至当t1一点,我们看到,主线程能够append到正在使用的flagt2理解它必须返回,因此最终名单。因此:time.sleep只会阻塞正在执行的线程。

+0

感谢mementum的详细示例。我刚刚添加了整个场景,请问您可以对此进行评论吗? –

+0

正如其他人所评论的那样,现在看到您的完整代码,问题在于您阻止了主线程。使用A. Jesse Jiryu Davis建议的提示 – mementum

2

龙卷风永远不会为你产生线程*如果你调用time.sleep,它会在睡眠期间阻塞整个过程;没有其他处理进行。这就是为什么文档说"time.sleep should not be used in coroutines because it is blocking"。要明确暂停协程和控制权返回给IOLoop以便其他处理可以继续:

yield gen.sleep(0.5) 

*龙卷风可以催生一个DNS解析线程或当你明确地使用ThreadPoolExecutor的制作任务异步。但您可以忽略这些讨论的案例。

+0

另一个小问题,如果我想在一些已经返回值的函数中使用yield gen.sleep(0.5)会怎么样? Python <3.3不支持。在这种情况下还能做什么? –

+0

要从Python 2中的协同程序返回值,请“提高gen.Return(value)”: http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.Return –

+0

我还在不明白。你能写一个简单的例子来解释吗? ' def add(x,y): yield gen.sleep(countdown); a = x + y; (a); 如何通过调用此函数来获取值a? –