[英]Python3 asyncio: parallel coroutines are unexpectedly blocking
I am trying to get two functions (coroutines) to work in parallel with shared reader, writer streams from a single open network connection like so: 我正在尝试使两个函数(协程)与共享的读取器,写入器流通过单个开放式网络连接并行运行,如下所示:
reader, writer = yield from asyncio.open_connection(
host, port, ssl=sc, loop=loop)
once the connection is open I can share it in two while loops as follows: 一旦连接打开,我可以在两个while循环中共享它,如下所示:
@asyncio.coroutine
def rvcr(loop)
while True:
data = yield from reader.readline()
# do something with it
@asyncio.coroutine
def xmtr(loop)
while True:
# get some data
writer.write(data)
Now I want to schedule these to run in a loop but not block each other. 现在,我想安排它们循环运行,但不会互相阻塞。 I have read many examples but asyncio is confusing me for some reason.
我已经阅读了许多示例,但是由于某种原因,asyncio使我感到困惑。
Some examples show 一些例子表明
loop = asyncio.get_event_loop()
asyncio.async(rcvr(loop))
asyncio.async(xmtr(loop))
loop.run_forever()
But the rcvr function blocks and I can't seem to pass reader and writer in correctly. 但是rcvr功能块,我似乎无法正确传递读写器。 I'm thinking this is a no brainer but for some reason I fail.
我认为这是毫无道理的,但是由于某种原因我失败了。
Can anyone please help. 谁能帮忙。
Ok I got it working, here is a complete example, the only thing I really need is to find a way to cleanly shut it down on Ctrl-C. 好的,我可以正常工作了,这是一个完整的示例,我唯一需要做的就是找到一种在Ctrl-C上完全关闭它的方法。 This will work with or without ssl encryption.
无论使用或不使用ssl加密,都可以使用。
#!/usr/bin/python3
"""
Openssl certifcate and key pairs can be created with the following command:
openssl req -x509 -newkey rsa:2048 -keyout selfsigned.key -nodes -out selfsigned.cert -sha256 -days 1000
Store your cert file in the same location as this file.
for testing ssl server
This is like telnet localhost:12345 but using your cert and key
openssl s_client -connect localhost:12345
"""
import os
import sys
import ssl
import asyncio
# --------------------- User configurable settings ---------------------------------
host = '127.0.0.1'
port = 8088
#sslcert = './mycert.cert'
sslcert = None
# ===================== End of user configurable settings ==========================
@asyncio.coroutine
def conn(loop):
if sslcert != None and not os.path.isfile(sslcert):
print("You certificate file {} seems to be missing...".format(sslcert))
sys.exit()
if sslcert != None:
sc = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
cafile=sslcert)
else:
sc=None
print("Opening connection to {} on port {}...".format(host, port))
try:
reader, writer = yield from asyncio.open_connection(
host, port, ssl=sc, loop=loop)
print("Connected...")
except:
print("Connection Failed, check your host name or IP address and port...")
sys.exit()
return reader,writer
@asyncio.coroutine
def rcvr(r):
print("Dropping into receive loop...")
while True:
rsp = yield from r.readline()
print(rsp)
yield from asyncio.sleep(.1)
@asyncio.coroutine
def xmtr(w):
print("Dropping into transmitter loop...")
while True:
yield from asyncio.sleep(0.05) # need this to yield control back to the loop
w.write("Some data...\n".encode())
yield from w.drain()
if __name__ == '__main__':
try:
loop = asyncio.get_event_loop()
reader,writer = loop.run_until_complete(conn(loop))
tasks = [loop.create_task(rcvr(reader)), loop.create_task(xmtr(writer))]
wait_tasks = asyncio.wait(tasks)
loop.run_until_complete(wait_tasks)
except KeyboardInterrupt:
print("Quiting...")
finally:
loop.close()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.