Потоки ненастоящие? GIL в Python

Поділитися
Вставка
  • Опубліковано 5 лип 2024
  • В этом видео мы разоблачим иллюзию относительно быстроты работы потоков в Python. GIL превращает все объекты в потокобезопасные, но платим за это мы производительностью, и на самом деле потоки очень редко работают по-настоящему параллельно. Разбираемся, в каких ситуациях их можно использовать с выгодой.
    Канал в тг, где я делюсь своими мыслями по видосам и не только - t.me/PythonClinicChnl
    Таймкоды:
    00:00 - интро
    00:36 - что такое GIL
    03:22 - CPU-bound
    07:03 - IO-bound
    10:02 - выводы
    12:48 - аутро

КОМЕНТАРІ • 23

  • @maximsheleh9603
    @maximsheleh9603 Рік тому +1

    спасибо

  • @Enerdzizer
    @Enerdzizer 2 місяці тому

    Ну не так, потоки в питоне могут выполняться одновременно , например когда используется библиотека numpy. Не может одновременно выполняться две инструкции самого интерпретатора например два умножения

  • @sportsman3109
    @sportsman3109 Рік тому +1

    Хотелось бы узнать, как часто вы использовали многопоточность и многопроцессорность на практике и будет ли видео про асинхронность?) И очень жаль, что видосы будут выходить реже(

    • @pythonclinic
      @pythonclinic  Рік тому +3

      вот как раз асинхронностью пользуюсь регулярно, мнопроцессностью пару раз доводилось по назначению, для распределения нагрузки при обработке большого количетсва данных
      видео по асинхронности будет примерно через одну неделю)

  • @MrLotrus
    @MrLotrus Рік тому

    Одна из тем, где я чувствую себя неуверенно, как питонист без базы в CS) Поэтому такие вопросы интересуют и очень интересно какую книгу или статьи лучше почитать на эту тему.
    1. Было бы интересно послушать про настоящую многопоточность без GIL. Что же такого дает ОС, чего мы лишены из-за GIL. И как тогда в других языках решается проблема доступа к общей памяти между потоками. Как я понимаю, процесс может занимать ресурсы сразу нескольких ядер процессора. И раскидывать потоки по ним. Вот этого мы лишены. А решение проблем с общей памятью передано в руки пользователям языка и авторам библиотек. Опять же в го своя история с горутинами. Там другой подход, когда поверх планировщика ОС с его потоками создан свой планировщик и своя сущность в виде гринлет/горутин.
    2. В примере с файлом - настоящая параллельность появляется за счет того, что мы отправили системный вызов на запись данных в файл, а ОС сама на другом процессоре начала эту операцию?

    • @pythonclinic
      @pythonclinic  Рік тому

      1. да, в го интересные потоки, "зелёные") проблема доступа для потоков решается точно так же, как и в случае с процессами - локами и семафорами, просто где-то это можно тонко контролировать руками, а кое-где у нас есть один общий лок на все ресурсы)
      2. да, за счёт того, что мы просим операционную систему что-то сделать, и ждём ответа от неё, а пока ждём моожно запустить следующий поток, это немного даже на асинхронность похоже
      что касается железа - тут всё сложно, в рамках работы самого интерпретатора поток будет работать на том же ядре, что и процесс, но когда мы отдадим что-то на запись в файл, трудно предсказать, будет это другое ядро, или то же самое, в конце концов бывают же в теории и одноядерные машины, и там тоже можно добиваться параллельности

    • @MrLotrus
      @MrLotrus Рік тому

      @@pythonclinic а вот если говорить о многопоточности на одном ядре, то в питоне она медленней чем реализация на с, например? процессор за один такт всё равно только одну операцию выполняет. Так что, как я понимаю, мы полной параллельности не добьемся и так. За счёт чего потоки на одном ядре на с будут быстрее потоков питона с Гил, работающих также на одном ядре?

    • @Devil666face
      @Devil666face Рік тому

      @@MrLotrus Один процессор в n еденицу времени выполняет паралельно x процессов = кол-ву ядер, одно ядро в n еденицу времени выполняет паралельно y потоков = кол-ву потоков на ядро. Возьми характеристику любого проца 16 ядер по 32 потока. Значит что паралельно (за один такт) выполняется 512 потоков. "За счёт чего потоки на одном ядре на с будут быстрее потоков питона с Гил, работающих также на одном ядре". - за счет того, что С позволяет запускать потоки одновременно (паралельно друг с другом). А сколько бы ты не дал потоков питону, они все будут работать последовательно, по очереди. Единственный способ запустить паралельную обработку - использовать процессы. Но запуск каждого процесса (не говоря уже про обмен данными между процессами) будет требовать очень много накладных расходов. Поэтому для цпу бунд задач, лучше не использовать питон, но если очень хочется то можешь глянуть сюда (github.com/colesbury/nogil)

    • @MrLotrus
      @MrLotrus Рік тому

      @@Devil666face спасибо. Для параллельной многопоточности используются Hyper-Threading от Интел и SMT от AMD, правильно понимаю? И есть современные процессоры без этого функционала.

  • @codecode5962
    @codecode5962 Рік тому

    Всегда интересовал вопрос когда в Python стоит отдать предпочтение потокам вместо асинхронности? Вроде как корутины более легковесные.. для каких практических применений подойдёт тот или иной подход и что проще с точки зрения программирования / поддержки?

    • @pythonclinic
      @pythonclinic  Рік тому +1

      ну кстати потоки намного проще с точки зрения работы с ними, я бы использовал потоки везде, где нужно ускорить работу с файловой системой и другим простейшим io, но например для http запросов я бы использовал уже корутины, ну и в принципе при работе с юзер интерфейсом корутины это отличный выбор

  • @Andrew-xb3nv
    @Andrew-xb3nv Рік тому

    GIL - это не баг, а фича. 🙂 Также интересной темой в являются сабинтерпритаторы.

    • @pythonclinic
      @pythonclinic  Рік тому +1

      да я в целом согласен)

  • @evevideo100
    @evevideo100 29 днів тому

    все объекты в потокобезопасные - не правда для сложных обьектов как panda dataframe. Пришлось сделать семафор и включать когда записывал в него. иначе обьект был битый.

    • @pythonclinic
      @pythonclinic  29 днів тому +1

      GIL работает не всегда, поэтому конечно же не прямо вот все-все-все объекты потокобезопасные

  • @user-it3yo1sn6i
    @user-it3yo1sn6i Рік тому

    Вывод прост, используем потоки там где есть IO.... Остальное от лукавого

  • @Scr1pted
    @Scr1pted Рік тому

    О Вердант, как там твич?

    • @pythonclinic
      @pythonclinic  Рік тому

      увы, не хватает времени пока что

    • @Scr1pted
      @Scr1pted Рік тому

      @@pythonclinic печалька, если что дай знать

  • @user-qKjP
    @user-qKjP Рік тому

    Скорее всего ввод-вывод уходит в систему IO_URING.

    • @pythonclinic
      @pythonclinic  Рік тому

      скорее всего да, в случае линукса

  • @blowyourbra1n233
    @blowyourbra1n233 Рік тому

    здравствуйте!
    а выгодно ли использовать потоки при работе с сетью? я пишу много роботов для торговли криптовалютой, иногда роботы нацелены на работу с десятками юзеров, у каждого свои API ключи, когда мне нужно соверишить какое-то действие (чаще всего это цепочка действий) - я просто в цикле открываю поток на каждого юзера, и иногда внутри этих потоков я разворачиываю еще потоки с бесконечными циклами и time.sleep(n)?
    Уточняю: внутри потоков обычно нет никаких вычислений, просто реквесты на биржу

    • @pythonclinic
      @pythonclinic  Рік тому

      да, вполне, запрос по сети это тоже своего рода io, потоки будут работать правильно
      можно опять таки на асинхронность посмотреть ещё)