2016-03-28 82 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? –