Tôi muốn kết nối với một danh sách nhiều trang web khác nhau rất nhanh. Im sử dụng asyncio để thực hiện việc này theo cách không đồng bộ và bây giờ muốn thêm thời gian chờ cho thời điểm kết nối sẽ bị bỏ qua nếu mất quá nhiều thời gian để phản hồi.Làm cách nào để thêm thời gian chờ kết nối với asyncio?
Làm cách nào để triển khai tính năng này?
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)
(Trên một sidenote: Có ai đó một ý tưởng làm thế nào để tối ưu hóa này?)
Bạn quên 'thu hút từ' các lệnh gọi đến 'q.put (None)' bên trong 'load_q', vì vậy mã này sẽ không hoạt động như hiện được viết. – dano
bạn không cần người đọc, nhà văn ở đây. Bạn có thể sử dụng 'asyncio.create_connection' với 'Protocol' mà không làm gì cả (nó đóng kết nối mạng ngay sau khi nó được thiết lập). Đây là [ví dụ mã mà tôi đã thử trên top triệu danh sách trang web Alexa] (http://stackoverflow.com/a/20722204/4279) (có thể hơi lỗi thời ví dụ, nó không sử dụng một số chức năng đối kháng như ' asyncio.wait_for() '). Nó sử dụng một luồng đơn và mở tối đa các kết nối ssl 'giới hạn'. – jfs