簡體   English   中英

Python3異步:並行協程意外阻塞

[英]Python3 asyncio: parallel coroutines are unexpectedly blocking

我正在嘗試使兩個函數(協程)與共享的讀取器,寫入器流通過單個開放式網絡連接並行運行,如下所示:

reader, writer = yield from asyncio.open_connection(
                    host, port, ssl=sc, loop=loop)

一旦連接打開,我可以在兩個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)

現在,我想安排它們循環運行,但不會互相阻塞。 我已經閱讀了許多示例,但是由於某種原因,asyncio使我感到困惑。

一些例子表明

loop = asyncio.get_event_loop()
asyncio.async(rcvr(loop))
asyncio.async(xmtr(loop))
loop.run_forever()

但是rcvr功能塊,我似乎無法正確傳遞讀寫器。 我認為這是毫無道理的,但是由於某種原因我失敗了。

誰能幫忙。

好的,我可以正常工作了,這是一個完整的示例,我唯一需要做的就是找到一種在Ctrl-C上完全關閉它的方法。 無論使用或不使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM