Почему при больших данных виснет asyncio?

async def run(r):
    tasks = []
    sem = asyncio.Semaphore(1000)

    async with ClientSession() as session:
        for url in r:
            task = asyncio.ensure_future(bound_fetch(sem, url, session))
            tasks.append(task)

        responses = await asyncio.gather(*tasks)

with open('0.txt') as f:
    urls = f.read().splitlines()

que = []
for url in urls:
    que.append(url)

    if len(que) == 5000:
        loop = asyncio.get_event_loop()
        future = asyncio.ensure_future(run(que))
        loop.run_until_complete(future)
        que = []

loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run(que))
loop.run_until_complete(future)


Я подаю в потоки массив по 5000 элементов, если убрать эту часть и подать весь массив из 1млн, то виснет практически моментально. Если подавать слайсами по 5к начинает виснуть примерно через пару минут.

Где ошибка?
  • Вопрос задан
  • 186 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Ты грузишь весь миллион адресов в память, дважды.
Первый раз, когда делаешь f.read(), потом в рамках .splitlines() создаётся копия (разбитая по кусочкам-строкам).
Ну и да, миллион индивидуальных тасков - это тоже дохрена. asyncio ведь надо проверить, может ли тот или иной таск продолжить работу.

Я бы сделал фиксированного размера пул тасков-воркеров , и заставил каждого воркера в цикле делать f.readline() самостоятельно, чтобы получить url для загрузки. И весь список в памяти хранить не надо, и контроль над количеством тасков получше.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы