2016-03-28 1 views
2

Я просто пытаюсь понять, что если при вызове time.sleep (x) текущий поток, который запускает код, задерживается на х секунд. Но это освобождает процессор за эти x секунд или поток поддерживает ресурсы самостоятельно, и через х секунд он просто начинает выполнять следующие строки кода.time.sleep() function

Редактирование с точным сценарием я столкнулся:

Вот так со мной:

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() 

Теперь, так как это Tornado будет один сервер резьбовую, что именно делает time.sleep (5) в этом случае (будет ли он просто блокировать поток в течение 5 секунд, делая весь процесс синхронным), или сопрограмма порождает новый поток?

+2

Будет ли иметь смысл запускать процессор и предотвращать выполнение любого другого потока? Может быть, вы можете это выяснить? –

+3

Возможно, это может вам помочь: http://stackoverflow.com/questions/92928/time-sleep-sleeps-thread-or-process – Querenker

+0

Простой ответ заключается в том, что он освободит процессор, но реализация может отличаться. Существует функция, известная как «блокировка спина» *, при которой поток сохраняет CPU, если ожидание находится на короткое время. Вполне возможно, что реализация может использовать блокировку спина для короткого времени сна, особенно в Windows, где для этого есть API. См. Также 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-multithread-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 (1-й поток) блокируется в течение длительного time.sleep из 10 секунд, работает 2-й поток t2.

И даже когда t1 будет сделано, мы видим, что основной поток способен append в список, который используется в качестве flag, чтобы t2 понять, что должен вернуться и, следовательно, конец.

So: time.sleep только блокирует нить, в которой выполняется.

+0

Спасибо за подробный пример. Я только что добавил весь сценарий, в котором я участвую, можете ли вы прокомментировать это? –

+0

Как прокомментировали другие и теперь видите полный код, проблема в том, что вы блокируете основной поток. Используйте подсказку, предложенную A. Jesse Jiryu Davis – mementum

2

Tornado никогда не порождает нити для вас. * Если вы вызываете 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, "raise gen.Return (value)": http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.Return –

+0

Я все еще не понимаю. Можете ли вы написать краткий пример, чтобы объяснить? ' def add (x, y): выход gen.sleep (обратный отсчет); a = x + y; raise gen.Return (a); Как получить значение a, вызвав эту функцию? –