time.sleep()函数

时间:2016-03-28 10:11:55

标签: python tornado

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

使用我面临的确切场景进行编辑:

以下是我的情况:

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 个答案:

答案 0 :(得分: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完成,我们也看到主线程能够appendflag列表中,t2time.sleep了解它必须返回并因此结束。

所以:[HttpPost] public ActionResult Meeting(ViewModel ViewModel) { //The Error appears if the following part isnt commented out --> //var ALL = db.Sites.Where(p => p.Content.Any(a => a.Date.CompareTo(DateTime.Now) <= 0)).OrderBy(l => l.Customer.Service).ToList(); //Adding informations that arnt added by user ViewModel.Changing.LastUpdate = DateTime.Now; ViewModel.Changing.LastUpdaterId = UpdaterID; Site current = ViewModel.Changing; if (ModelState.IsValid) { db.Entry(current).State = EntityState.Modified; //Here is the error db.SaveChanges(); } //... } 只阻止正在执行的线程。

答案 1 :(得分:2)

Tornado永远不会为你生成一个线程。*如果你调用time.sleep,它会在睡眠期间阻止整个过程;没有其他处理收益。这就是文档说"time.sleep should not be used in coroutines because it is blocking"的原因。要显式暂停协程并将控制权返回给IOLoop,以便继续进行其他处理:

yield gen.sleep(0.5)

* Tornado可以为DNS解析生成线程,或者当您明确使用ThreadPoolExecutor使任务异步时。但是你可以忽略这些案例进行讨论。