12.10 Асинхронные возможности Python

Краткий пересказ теории

В действительности:

Синтаксический сахар и асинхронный протокол:

Asyncio

  1. Напишем программу сортировки слиянием массива из 16 элементов
    • Все 15 слияний делать руками с помощью вызова функции слить(начало1, конец1, начало2, конец2)

    • Для слияния используется общий глобальный второй массив
  2. {i} Перетащим их в структуру asyncio.run()/await 

    • Для наглядности снабдим каждый шаг сортировки await asyncio.sleep(0.1) и выводом номера «задания» (передадим его в качестве пятого параметра)

    • Разницы никакой, всё равно запуск последовательный

  3. Для придания асинхронности надо писать свой mainloop. Но он уже есть — это asyncio.run(). Не надо писать свой mainloop, надо пользоваться asyncio.create_task() и asyncio.gather(все 15 слияний)

    • Получается какая-то каша вместо сортировки, почему?
    • {i} Эшелонируем сортировку с помощью нескольких фрагментов вида create_task()… + gather(все_таски_из фрагмента) (палево — их пять)

  4. Эшелонируем сортировку с помощью задания тайм-аута (в пятом параметре будем передавать номер эшелона n и ждать n/c секунд) и общего create_task() / gather()

    • Чем этот подход плох?
  5. Фьюча (future).
    • Алгоритм работы
      1. Awaitable-объект, у которого есть творец и адресат, оба имеют к нему доступ.
      2. Адресат делает результат = await фьюча, и уходит в mainloop.

      3. Творец, когда ему заблагорассудится, с помощью фьюча.set_result(что-то) объявляет mainloop-у, что будущее наступило с результатом что-то

      4. Тогда mainloop, наконец, активизирует эту фьючу и адресат просыпается
    • В действительности, фьюча — это просто генератор на два шага: будушее не наступило / yield / будущее наступило, в котором есть два дополнительных поля (объявление о том, что оно наступило и передаваемое значение)
  6. Задача_1: переписать сортировку с использованием future для синхронизации (например, слияние_4_8 должно дожидаться двух фьюч — фьюча_4_6 и фьюча_6_8)

  7. Задача_2: (на дом). Переписать сортировку под произвольный (не слишком большой) объём данных