我只是想了解如果我调用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秒钟使整个进程同步)或者协同程序产生一个新线程?
答案 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
完成,我们也看到主线程能够append
到flag
列表中,t2
让time.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使任务异步时。但是你可以忽略这些案例进行讨论。