【发布时间】:2018-01-29 17:06:41
【问题描述】:
我想使用 asyncio 协程而不是多线程来重新实现我的代码。
server.py
def handle_client(client):
request = None
while request != 'quit':
request = client.recv(255).decode('utf8')
response = cmd.run(request)
client.send(response.encode('utf8'))
client.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 15555))
server.listen(8)
try:
while True:
client, _ = server.accept()
threading.Thread(target=handle_client, args=(client,)).start()
except KeyboardInterrupt:
server.close()
client.py
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect(('localhost', 15555))
request = None
try:
while request != 'quit':
request = input('>> ')
if request:
server.send(request.encode('utf8'))
response = server.recv(255).decode('utf8')
print(response)
except KeyboardInterrupt:
server.close()
我知道有一些合适的异步网络库可以做到这一点。但我只是想在这个案例上只使用 asyncio 核心库,以便更好地理解它。
在处理客户端定义之前只添加 async 关键字会非常好...这里有一段代码似乎可以工作,但我仍然对实现感到困惑。
asyncio_server.py
def handle_client(client):
request = None
while request != 'quit':
request = client.recv(255).decode('utf8')
response = cmd.run(request)
client.send(response.encode('utf8'))
client.close()
def run_server(server):
client, _ = server.accept()
handle_client(client)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 15555))
server.listen(8)
loop = asyncio.get_event_loop()
asyncio.async(run_server(server))
try:
loop.run_forever()
except KeyboardInterrupt:
server.close()
如何以最佳方式适应这一点并使用 async await 关键字。
【问题讨论】:
-
您是否已经完成了一些完全专注于
asyncio的教程?首先这样做可能更谨慎,而不是翻译你已经在工作的东西。我会推荐 this 让你开始。 -
我已经更新了这个问题。由于我仍然对 asyncio 库感到困惑,我认为这个用例可能有助于更好地理解。
-
如果你仍然对 asyncio 感到困惑(它确实是一堆futures、tasks 和 coroutines)并且想要避免线程,你可以尝试
gevent,它是一个完善的协程库,或者,imo最好的选择,依靠操作系统的select函数。这是 Python 3 documentation 和快速教程 Wait for IO Efficiently
标签: python sockets python-asyncio