Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Асинхронщина в Python

Асинхронщина в Python

Александр Полищук (ООО "Код безопасности") @ Moscow Python Meetup 52
"Python – это замечательный язык программирования, но есть одна вещь, которая ограничивает нашу свободу творчества, и называется она GIL. Спикер расскажет, как можно с ним договориться и не ограничивать себя одним потоком".
Видео: http://www.moscowpython.ru/meetup/52/asyncronous-python/

Moscow Python Meetup
PRO

January 24, 2018
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Асинхронщина в Python
    Александр Полищук
    ООО «Код Безопасности»
    @alpolishchuk

    View Slide

  2. Последовательный вызов
    print("Welcome to")
    print("MoscowPython")
    print("MeetUp!")

    View Slide

  3. Последовательный вызов
    print("Welcome to")
    print("MoscowPython")
    print("MeetUp!")
    >> Welcome to
    >> MoscowPython
    >> MeetUp!

    View Slide

  4. Как можно делать одновременно несколько
    вещей в Python

    View Slide

  5. Как можно делать одновременно несколько
    вещей в Python
    • Отдельные процессы

    View Slide

  6. Как можно делать одновременно несколько
    вещей в Python
    • Отдельные процессы
    • Отдельные потоки

    View Slide

  7. Как можно делать одновременно несколько
    вещей в Python
    • Отдельные процессы
    • Отдельные потоки
    • Асинхронный код

    View Slide

  8. Отдельные процессы это хорошо

    View Slide

  9. Отдельные процессы это хорошо
    • Отдельные программы

    View Slide

  10. Отдельные процессы это хорошо
    • Отдельные программы
    • Изолированы

    View Slide

  11. Отдельные процессы это хорошо
    • Отдельные программы
    • Изолированы
    • Работают параллельно

    View Slide

  12. Отдельные процессы это хорошо
    • Отдельные программы
    • Изолированы
    • Работают параллельно
    • Используют все ресурсы процессора

    View Slide

  13. Отдельные процессы это плохо

    View Slide

  14. Отдельные процессы это плохо
    • Нет разделяемых переменных

    View Slide

  15. Отдельные процессы это плохо
    • Нет разделяемых переменных
    • Необходима синхронизация

    View Slide

  16. Отдельные процессы это плохо
    • Нет разделяемых переменных
    • Необходима синхронизация
    • Очень затратные

    View Slide

  17. Отдельные процессы это плохо
    • Нет разделяемых переменных
    • Необходима синхронизация
    • Очень затратные
    • Зависят от количества ядер

    View Slide

  18. Где же это использовать?

    View Slide

  19. Где же это использовать?
    • Обработка изображений

    View Slide

  20. Где же это использовать?
    • Обработка изображений
    • Обработка массивов данных

    View Slide

  21. Где же это использовать?
    • Обработка изображений
    • Обработка массивов данных
    • Обработка матриц

    View Slide

  22. Библиотеки

    View Slide

  23. Библиотеки
    • multiprocessing

    View Slide

  24. Пример
    from multiprocessing import Pool
    def print_word(word):
    print(word)
    If __name__ == "__main__":
    pool = Pool()
    pool.map(print_word, ["Hello", "MoscowPython", "Meetup"])
    pool.close()
    pool.join()

    View Slide

  25. Результат
    Hello
    MoscowPython
    Meetup

    View Slide

  26. Пример из жизни
    import os
    from PIL import Image
    from multiprocessing import Pool
    def create_thumbnail(filename):
    im = Image.open(filename)
    im.thumbnail((75, 75), Image.ANTIALIAS)
    save_path = os.path.join(".", "thumbnails", fname)
    im.save(save_path)
    if __name__ == "__main__":
    images = [file for file in os.listdir(".") if "jpeg" in file]
    pool = Pool()
    pool.map(create_thumbnail, images)
    pool.close()
    pool.join()

    View Slide

  27. Отдельные потоки это хорошо

    View Slide

  28. Отдельные потоки это хорошо
    • Общая память

    View Slide

  29. Отдельные потоки это хорошо
    • Общая память
    • Общие глобальные переменные

    View Slide

  30. Отдельные потоки это хорошо
    • Общая память
    • Общие глобальные переменные
    • Не требуют больших ресурсов

    View Slide

  31. Отдельные потоки это хорошо
    • Общая память
    • Общие глобальные переменные
    • Не требуют больших ресурсов
    • Отлично подходит для I/O-bound операций

    View Slide

  32. Отдельные потоки это плохо

    View Slide

  33. Отдельные потоки это плохо
    • GIL

    View Slide

  34. Отдельные потоки это плохо
    • GIL
    • Нельзя использовать CPU-bound функции

    View Slide

  35. Отдельные потоки это плохо
    • GIL
    • Нельзя использовать CPU-bound функции
    • Код не тривиален

    View Slide

  36. Отдельные потоки это плохо
    • GIL
    • Нельзя использовать CPU-bound функции
    • Код не тривиален
    • Одновременный доступ к памяти

    View Slide

  37. Где же это использовать?

    View Slide

  38. Где же это использовать?
    • Работа с сетью

    View Slide

  39. Библиотеки

    View Slide

  40. Библиотеки
    • threading

    View Slide

  41. Пример
    import threading
    def worker(num):
    """thread worker function"""
    print 'Worker: %s' % num
    return
    threads = []
    for i in range(5):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

    View Slide

  42. Результат
    Worker: 0
    Worker: 1
    Worker: 2
    Worker: 3
    Worker: 4

    View Slide

  43. Пример из жизни
    ДА ПРОСТИТ МЕНЯ
    PEP

    View Slide

  44. Пример из жизни
    import threading, requests
    def pinger(url):
    return requests.get(url)
    e1 = threading.Event(); e2 = threading.Event()
    t1 = threading.Thread(target=pinger, args=('https://yandex.ru',))
    t2 = threading.Thread(target=pinger, args=('https://mail.ru',))
    t1.start(); t2.start()
    e1.set()
    t1.join(); t2.join()

    View Slide

  45. Асинхронный код это хорошо

    View Slide

  46. Асинхронный код это хорошо
    • Выполнение в одном процессе и потоке

    View Slide

  47. Асинхронный код это хорошо
    • Выполнение в одном процессе и потоке
    • Очень малое использование ресурсов
    системы

    View Slide

  48. Асинхронный код это хорошо
    • Выполнение в одном процессе и потоке
    • Очень малое использование ресурсов
    системы
    • ОС независим

    View Slide

  49. Асинхронный код это плохо

    View Slide

  50. Асинхронный код это плохо
    • Сложность отладки

    View Slide

  51. Асинхронный код это плохо
    • Сложность отладки
    • Трудно понять, в каком контексте мы
    находимся

    View Slide

  52. Асинхронный код это плохо
    • Сложность отладки
    • Трудно понять, в каком контексте мы
    находимся
    • Сложночитаемый код

    View Slide

  53. Асинхронный код это плохо
    • Сложность отладки
    • Трудно понять, в каком контексте мы
    находимся
    • Сложночитаемый код
    • «Очень легко выстрелить себе в ногу» (с)

    View Slide

  54. Библиотеки

    View Slide

  55. Библиотеки
    • Asyncio

    View Slide

  56. Библиотеки
    • Asyncio
    • gevent

    View Slide

  57. Пример
    import asyncio
    async def hello_world():
    print("Hello Meetup!")
    loop = asyncio.get_event_loop()
    loop.run_until_complete(hello_world())
    loop.close()

    View Slide

  58. Результат
    Hello Meetup!

    View Slide

  59. Пример из жизни
    import requests
    import asyncio
    async def ping_url(url):
    return requests.get(url)
    loop = asyncio.get_event_loop()
    tasks = [ping_url('https://yandex.ru'), ping_url('https://mail.ru')]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

    View Slide

  60. Итоги

    View Slide

  61. Итоги
    Multiprocessing
    • Работают
    параллельно
    • Использует все
    ядра
    • Максимум пара
    десятков

    View Slide

  62. Итоги
    • Работают
    «параллельно»
    • Использует
    одно ядро
    • Максимум
    несколько сотен
    Multiprocessing Threading
    • Работают
    параллельно
    • Использует все
    ядра
    • Максимум пара
    десятков

    View Slide

  63. Итоги
    Async
    • Работают
    «параллельно»
    • Использует
    одно ядро
    • Максимум
    несколько сотен
    Multiprocessing Threading
    • Работают
    конкурентно
    • Использует
    одно ядро и
    один поток
    • Тысячи
    • Работают
    параллельно
    • Использует все
    ядра
    • Максимум пара
    десятков

    View Slide

  64. Спасибо за внимание

    View Slide

  65. Спасибо за внимание
    Twitter: @alpolishchuk

    View Slide

  66. Спасибо за внимание
    Twitter: @alpolishchuk
    Facebook: alxpolishchuk

    View Slide

  67. Спасибо за внимание
    Twitter: @alpolishchuk
    Facebook: alxpolishchuk
    E-mail: [email protected]

    View Slide