d51*_*512 5 python multithreading asynchronous timer python-asyncio
我是python的ascynio功能的新手,我有一个服务器来处理来自浏览器的websocket请求.这是它的工作原理的简化版本:
@asyncio.coroutine
def web_client_connected(self, websocket):
self.web_client_socket = websocket
while True:
request = yield from self.web_client_socket.recv()
json_val = process_request(request)
yield from self.socket_queue.put(json_val)
@asyncio.coroutine
def push_from_web_client_json_queue(self):
while True:
json_val = yield from self.socket_queue.get()
yield from self.web_client_socket.send(json_val)
Run Code Online (Sandbox Code Playgroud)
您有一个循环正在查找来自客户端的Web套接字请求.当它获得一个时,它处理它并将值放入队列.另一个循环是在该队列上查找值,当它找到一个时,它会在Web套接字上发回处理后的值.相当直接,它的工作原理.
我现在要做的是它引入一个计时器.当请求到来并且处理完毕,而不是立即将响应放回队列时,我想启动计时器1分钟.当计时器完成时,我想将响应放在队列上.
我尝试过类似的东西:
@asyncio.coroutine
def web_client_connected(self, websocket):
self.web_client_socket = websocket
while True:
request = yield from self.web_client_socket.recv()
json_val = process_request(request)
t = threading.Timer(60, self.timer_done, json_val)
t.start()
@asyncio.coroutine
def timer_done(self, args):
yield from self.socket_queue.put(args)
Run Code Online (Sandbox Code Playgroud)
它不起作用.timer_done永远不会调用该方法.如果我删除了@asyncio.coroutine装饰器yield from,然后timer_done调用,但然后调用self.socket_queue.put(args)不起作用.
我想我在这里误解了一些基本的东西.你怎么做到这一点?
安装计时器,使用asyncio.ensure_future()和 asyncio.sleep():
@asyncio.coroutine
def web_client_connected(self, websocket):
self.web_client_socket = websocket
while True:
request = yield from self.web_client_socket.recv()
json_val = process_request(request)
asyncio.ensure_future(web_client_timer(json_val))
yield
@asyncio.coroutine
def web_client_timer(self, json_val):
yield from asyncio.sleep(60)
yield from self.socket_queue.put(json_val)
Run Code Online (Sandbox Code Playgroud)
工作示例:
import asyncio
@asyncio.coroutine
def foo():
print("enter foo")
timers = []
for i in range(10):
print("Start foo", i)
yield from asyncio.sleep(0.5)
print("Got foo", i)
timers.append(asyncio.ensure_future(timer(i)))
yield
print("foo waiting")
# wait for all timers to finish
yield from asyncio.wait(timers)
print("exit foo")
@asyncio.coroutine
def timer(i):
print("Setting timer", i)
yield from asyncio.sleep(2)
print("**** Timer", i)
loop = asyncio.get_event_loop()
resp = loop.run_until_complete(foo())
loop.close()
Run Code Online (Sandbox Code Playgroud)