【发布时间】:2015-06-27 16:29:54
【问题描述】:
我想快速连接到许多不同站点的列表。 我使用 asyncio 以异步方式执行此操作,现在想要 如果连接响应时间过长,则应在连接被忽略时添加超时。
我该如何实现?
import ssl
import asyncio
from contextlib import suppress
from concurrent.futures import ThreadPoolExecutor
import time
@asyncio.coroutine
def run():
while True:
host = yield from q.get()
if not host:
break
with suppress(ssl.CertificateError):
reader, writer = yield from asyncio.open_connection(host[1], 443, ssl=True) #timout option?
reader.close()
writer.close()
@asyncio.coroutine
def load_q():
# only 3 entries for debugging reasons
for host in [[1, 'python.org'], [2, 'qq.com'], [3, 'google.com']]:
yield from q.put(host)
for _ in range(NUM):
q.put(None)
if __name__ == "__main__":
NUM = 1000
q = asyncio.Queue()
loop = asyncio.get_event_loop()
loop.set_default_executor(ThreadPoolExecutor(NUM))
start = time.time()
coros = [asyncio.async(run()) for i in range(NUM)]
loop.run_until_complete(load_q())
loop.run_until_complete(asyncio.wait(coros))
end = time.time()
print(end-start)
(旁注:有人知道如何优化这个吗?)
【问题讨论】:
-
您忘记了在
load_q中对q.put(None)的调用yield from,因此此代码将无法按照当前编写的方式运行。 -
这里不需要读者,作者。您可以将
asyncio.create_connection与Protocol一起使用,它什么都不做(它会在网络连接建立后立即关闭)。这是code example that I've tried on top million Alexa site list(它可能有点过时,例如,它不使用一些便利功能,例如asyncio.wait_for())。它使用单线程并最多打开limitssl 连接。
标签: python python-3.x asynchronous timeout python-asyncio