Global Interpreter Lock (GIL) — это способ синхронизации потоков, который используется в некоторых интерпретируемых языках программирования, например в Python и Ruby.
GIL является самым простым способом избежать конфликтов при одновременном обращении разных потоков к одним и тем же участкам памяти. Когда один поток захватывает его, GIL, работая по принципу мьютекса, блокирует остальные. Нет параллельных потоков — нет конфликтов при обращении к разделяемым объектам. Очерёдность выполнения потоков определяет интерпретатор в зависимости от реализации, переключение между потоками может происходить: когда активный поток пытается осуществить ввод-вывод, по исчерпании лимита выполненных инструкций либо по таймеру.
Главный недостаток подхода обеспечения потокобезопасности при помощи GIL — это ограничение параллельности вычислений. GIL не позволяет достигать наибольшей эффективности вычислений при работе на многоядерных и мультипроцессорных системах. Также использование нескольких потоков накладывает издержки на их переключение из-за эффекта конкуренции (потоки «пытаются» перехватить GIL). То есть многопоточное выполнение может занять большее время, чем последовательное выполнение тех же задач.
Причины использования GIL:
Однопоточные сценарии выполняются значительно быстрее, чем при использовании других подходов обеспечения потокобезопасности;
Простая интеграция библиотек на C, которые зачастую тоже не потокобезопасны;
Простота реализации.
GIL используется в CPython'е, наиболее распространённой реализации интерпретатора языка Python , и в Ruby MRI, эталонной реализации интерпретатора языка Ruby, где он зовётся Global VM Lock.
В сети не раз появлялись петиции и открытые письма с просьбой убрать GIL из Python'а. Однако создатель и «великодушный пожизненный диктатор» проекта Гвидо ван Россум заявляет, что GIL не так уж и плох и он будет в CPython'е до тех пор, пока кто-то другой не представит реализацию Python'а без GIL, с которой бы однопоточные скрипты работали так же быстро.
Реализации интерпретаторов на JVM (Jython, JRuby) и на .NET (IronPython, IronRuby) не используют GIL.
В рамках проекта PyPy ведётся работа по реализации транзакционной памяти (англ. Software Transactional Memory, SТМ). На данный момент даже в многопоточных вычислениях интерпретатор с STM работает во много раз медленней, чем с GIL. Но за счёт JIT PyPy-STM всё равно быстрее, чем CPython.
GIL является самым простым способом избежать конфликтов при одновременном обращении разных потоков к одним и тем же участкам памяти. Когда один поток захватывает его, GIL, работая по принципу мьютекса, блокирует остальные. Нет параллельных потоков — нет конфликтов при обращении к разделяемым объектам. Очерёдность выполнения потоков определяет интерпретатор в зависимости от реализации, переключение между потоками может происходить: когда активный поток пытается осуществить ввод-вывод, по исчерпании лимита выполненных инструкций либо по таймеру.
Главный недостаток подхода обеспечения потокобезопасности при помощи GIL — это ограничение параллельности вычислений. GIL не позволяет достигать наибольшей эффективности вычислений при работе на многоядерных и мультипроцессорных системах. Также использование нескольких потоков накладывает издержки на их переключение из-за эффекта конкуренции (потоки «пытаются» перехватить GIL). То есть многопоточное выполнение может занять большее время, чем последовательное выполнение тех же задач.
Причины использования GIL:
Однопоточные сценарии выполняются значительно быстрее, чем при использовании других подходов обеспечения потокобезопасности;
Простая интеграция библиотек на C, которые зачастую тоже не потокобезопасны;
Простота реализации.
GIL используется в CPython'е, наиболее распространённой реализации интерпретатора языка Python , и в Ruby MRI, эталонной реализации интерпретатора языка Ruby, где он зовётся Global VM Lock.
В сети не раз появлялись петиции и открытые письма с просьбой убрать GIL из Python'а. Однако создатель и «великодушный пожизненный диктатор» проекта Гвидо ван Россум заявляет, что GIL не так уж и плох и он будет в CPython'е до тех пор, пока кто-то другой не представит реализацию Python'а без GIL, с которой бы однопоточные скрипты работали так же быстро.
Реализации интерпретаторов на JVM (Jython, JRuby) и на .NET (IronPython, IronRuby) не используют GIL.
В рамках проекта PyPy ведётся работа по реализации транзакционной памяти (англ. Software Transactional Memory, SТМ). На данный момент даже в многопоточных вычислениях интерпретатор с STM работает во много раз медленней, чем с GIL. Но за счёт JIT PyPy-STM всё равно быстрее, чем CPython.
В Python есть одна проблема: есть глобальная блокировка интерпретатора, которая не позволяет двум потокам в одном и том же процессе одновременно запускать код Python. Это означает, что если у вас 8 ядер и вы измените код на использование 8 потоков, он не сможет использовать 800% ЦП и работать в 8 раз быстрее; он будет использовать тот же 100% процессор и работать с той же скоростью. (На самом деле, он будет работать немного медленнее, потому что при многопоточности возникают дополнительные издержки, даже если у вас нет общих данных, но пока игнорируйте это.)
Есть исключения из этого. Если тяжелые вычисления в вашем коде на самом деле не происходят в Python, но в какой-то библиотеке с пользовательским кодом C, которая выполняет правильную обработку GIL, например, в numpy-приложении, вы получите ожидаемый выигрыш в производительности от потоков. То же самое верно, если тяжелые вычисления выполняются каким-то подпроцессом, который вы запускаете и ждете.
Что еще более важно, есть случаи, когда это не имеет значения. Например, сетевой сервер тратит большую часть своего времени на чтение пакетов из сети, а приложение с графическим интерфейсом тратит большую часть своего времени на ожидание пользовательских событий. Одна из причин использования потоков в сетевом сервере или приложении с графическим интерфейсом - это возможность выполнять длительные «фоновые задачи», не останавливая основной поток от продолжения обслуживания сетевых пакетов или событий графического интерфейса. И это прекрасно работает с потоками Python. (С технической точки зрения это означает, что потоки Python обеспечивают параллелизм, даже если они не обеспечивают параллелизма ядра.)
Но если вы пишете программу с привязкой к процессору на чистом Python, использование большего количества потоков обычно не помогает.
Использование отдельных процессов не имеет таких проблем с GIL, потому что каждый процесс имеет свой отдельный GIL. Конечно, между потоками и процессами у вас все еще есть те же компромиссы, что и в любых других языках - разделять данные между процессами труднее и дороже, чем между потоками, может быть дорого запускать огромное количество процессов или создавать и уничтожать их часто и т. д. Но GIL сильно влияет на баланс между процессами, и это не так, скажем, для C или Java. Таким образом, вы обнаружите, что используете многопроцессорность гораздо чаще в Python, чем в C или Java.
Между тем, философия Python «включенные батареи» приносит некоторые хорошие новости: очень легко писать код, который можно переключать между потоками и процессами с помощью смены одной строки.
Если вы разрабатываете свой код в терминах автономных «заданий», которые ничего не делят с другими заданиями (или основной программой), кроме ввода и вывода, вы можете использовать concurrent.futures библиотеку для написания кода вокруг пула потоков, например:
Вы даже можете получить результаты этих заданий и передать их на дальнейшие задания, ждать, пока все будет в порядке выполнения или в порядке завершения и т. Д .; прочитайте раздел об Futureобъектах для деталей.
Теперь, если окажется, что ваша программа постоянно использует 100% ЦП, а добавление большего количества потоков просто замедляет ее, то вы столкнулись с проблемой GIL, поэтому вам нужно переключиться на процессы. Все, что вам нужно сделать, это изменить эту первую строку:
Единственное реальное предостережение в том, что аргументы и возвращаемые значения ваших заданий должны быть легко перестраиваемыми (и не требовать слишком много времени или памяти для перебора), чтобы их можно было использовать в перекрестном процессе. Обычно это не проблема, но иногда это так.
Но что, если ваша работа не может быть самостоятельной?
Есть исключения из этого. Если тяжелые вычисления в вашем коде на самом деле не происходят в Python, но в какой-то библиотеке с пользовательским кодом C, которая выполняет правильную обработку GIL, например, в numpy-приложении, вы получите ожидаемый выигрыш в производительности от потоков. То же самое верно, если тяжелые вычисления выполняются каким-то подпроцессом, который вы запускаете и ждете.
Что еще более важно, есть случаи, когда это не имеет значения. Например, сетевой сервер тратит большую часть своего времени на чтение пакетов из сети, а приложение с графическим интерфейсом тратит большую часть своего времени на ожидание пользовательских событий. Одна из причин использования потоков в сетевом сервере или приложении с графическим интерфейсом - это возможность выполнять длительные «фоновые задачи», не останавливая основной поток от продолжения обслуживания сетевых пакетов или событий графического интерфейса. И это прекрасно работает с потоками Python. (С технической точки зрения это означает, что потоки Python обеспечивают параллелизм, даже если они не обеспечивают параллелизма ядра.)
Но если вы пишете программу с привязкой к процессору на чистом Python, использование большего количества потоков обычно не помогает.
Использование отдельных процессов не имеет таких проблем с GIL, потому что каждый процесс имеет свой отдельный GIL. Конечно, между потоками и процессами у вас все еще есть те же компромиссы, что и в любых других языках - разделять данные между процессами труднее и дороже, чем между потоками, может быть дорого запускать огромное количество процессов или создавать и уничтожать их часто и т. д. Но GIL сильно влияет на баланс между процессами, и это не так, скажем, для C или Java. Таким образом, вы обнаружите, что используете многопроцессорность гораздо чаще в Python, чем в C или Java.
Между тем, философия Python «включенные батареи» приносит некоторые хорошие новости: очень легко писать код, который можно переключать между потоками и процессами с помощью смены одной строки.
Если вы разрабатываете свой код в терминах автономных «заданий», которые ничего не делят с другими заданиями (или основной программой), кроме ввода и вывода, вы можете использовать concurrent.futures библиотеку для написания кода вокруг пула потоков, например:
with
concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: executor.submit(job, argument) executor.map(some_function, collection_of_independent_things)
# ...Вы даже можете получить результаты этих заданий и передать их на дальнейшие задания, ждать, пока все будет в порядке выполнения или в порядке завершения и т. Д .; прочитайте раздел об Futureобъектах для деталей.
Теперь, если окажется, что ваша программа постоянно использует 100% ЦП, а добавление большего количества потоков просто замедляет ее, то вы столкнулись с проблемой GIL, поэтому вам нужно переключиться на процессы. Все, что вам нужно сделать, это изменить эту первую строку:
with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executorЕдинственное реальное предостережение в том, что аргументы и возвращаемые значения ваших заданий должны быть легко перестраиваемыми (и не требовать слишком много времени или памяти для перебора), чтобы их можно было использовать в перекрестном процессе. Обычно это не проблема, но иногда это так.
Но что, если ваша работа не может быть самостоятельной?
Если вы можете разработать свой код с точки зрения заданий, которые передают сообщения от одного к другому, это все еще довольно легко. Возможно, вам придется использовать threading.Threadили multiprocessing.Processвместо того, чтобы полагаться на пулы. И вам придется создавать объекты queue.Queueили multiprocessing.Queueявно. (Существует множество других опций - каналы, сокеты, файлы со скоплениями, ... но дело в том, что вы должны сделать что-то вручную, если автоматическая магия исполнителя недостаточна.)
Но что, если вы даже не можете положиться на передачу сообщений? Что делать, если вам нужно две работы, чтобы изменить одну и ту же структуру и увидеть изменения друг друга? В этом случае вам нужно будет выполнить ручную синхронизацию (блокировки, семафоры, условия и т. Д.) И, если вы хотите использовать процессы, явные объекты совместной памяти для загрузки. Это когда многопоточность (или многопроцессорность) становится сложной. И если вы можете избежать этого, то это прекрасно.
Но что, если вы даже не можете положиться на передачу сообщений? Что делать, если вам нужно две работы, чтобы изменить одну и ту же структуру и увидеть изменения друг друга? В этом случае вам нужно будет выполнить ручную синхронизацию (блокировки, семафоры, условия и т. Д.) И, если вы хотите использовать процессы, явные объекты совместной памяти для загрузки. Это когда многопоточность (или многопроцессорность) становится сложной. И если вы можете избежать этого, то это прекрасно.
В чем разница между потоком и процессом?
Процессы и потоки связаны друг с другом, но при этом имеют существенные различия.
Процесс — экземпляр программы во время выполнения, независимый объект, которому выделены системные ресурсы (например, процессорное время и память). Каждый процесс выполняется в отдельном адресном пространстве: один процесс не может получить доступ к переменным и структурам данных другого. Если процесс хочет получить доступ к чужим ресурсам, необходимо использовать межпроцессное взаимодействие. Это могут быть конвейеры, файлы, каналы связи между компьютерами и многое другое.
Поток использует то же самое пространства стека, что и процесс, а множество потоков совместно используют данные своих состояний. Как правило, каждый поток может работать (читать и писать) с одной и той же областью памяти, в отличие от процессов, которые не могут просто так получить доступ к памяти другого процесса. У каждого потока есть собственные регистры и собственный стек, но другие потоки могут их использовать.
Поток — определенный способ выполнения процесса. Когда один поток изменяет ресурс процесса, это изменение сразу же становится видно другим потокам этого процесса.
Процессы и потоки связаны друг с другом, но при этом имеют существенные различия.
Процесс — экземпляр программы во время выполнения, независимый объект, которому выделены системные ресурсы (например, процессорное время и память). Каждый процесс выполняется в отдельном адресном пространстве: один процесс не может получить доступ к переменным и структурам данных другого. Если процесс хочет получить доступ к чужим ресурсам, необходимо использовать межпроцессное взаимодействие. Это могут быть конвейеры, файлы, каналы связи между компьютерами и многое другое.
Поток использует то же самое пространства стека, что и процесс, а множество потоков совместно используют данные своих состояний. Как правило, каждый поток может работать (читать и писать) с одной и той же областью памяти, в отличие от процессов, которые не могут просто так получить доступ к памяти другого процесса. У каждого потока есть собственные регистры и собственный стек, но другие потоки могут их использовать.
Поток — определенный способ выполнения процесса. Когда один поток изменяет ресурс процесса, это изменение сразу же становится видно другим потокам этого процесса.
Учебник по Python: создание веб-приложения для опроса Discord с помощью Python
https://morioh.com/p/27207a7ebe8e?f=5c21fb01c16e2556b555ab32
https://morioh.com/p/27207a7ebe8e?f=5c21fb01c16e2556b555ab32
Morioh
Python Tutorial : How to Making a Discord polling web app with Python
After-hours coding session, making a polling web app with Python that uses Discord API for authentication.
В Китае стартуют продажи карт Super SIM
Эра сетей и смартфонов 5G принесла с собой «побочный» продукт в виде так называемой карты Super SIM. Как пишет источник, ее продажи в Китае стартуют уже 23 декабря.
За разработкой Super SIM стоит местная компания Ziguang, а самое главное ее отличие от обычной SIM – наличие 128 ГБ встроенной флэш-памяти. Применение такой SIM-карты позволит расширить память даже той модели, которая не поддерживает карты памяти microSD. Отмечается, что на Super SIM пользователи могут осуществлять резервное копирование данных или попросту копировать фото или видео – в любом случае данные будут надежно защищены.
128 ГБ – это максимальный объем флэш-памяти Super SIM, пользователям предложат варианты попроще – с 32 и 64 ГБ памяти. А в будущем объем флэш-памяти Super SIM увеличится до 512 ГБ и даже 1 ТБ.
Эра сетей и смартфонов 5G принесла с собой «побочный» продукт в виде так называемой карты Super SIM. Как пишет источник, ее продажи в Китае стартуют уже 23 декабря.
За разработкой Super SIM стоит местная компания Ziguang, а самое главное ее отличие от обычной SIM – наличие 128 ГБ встроенной флэш-памяти. Применение такой SIM-карты позволит расширить память даже той модели, которая не поддерживает карты памяти microSD. Отмечается, что на Super SIM пользователи могут осуществлять резервное копирование данных или попросту копировать фото или видео – в любом случае данные будут надежно защищены.
128 ГБ – это максимальный объем флэш-памяти Super SIM, пользователям предложат варианты попроще – с 32 и 64 ГБ памяти. А в будущем объем флэш-памяти Super SIM увеличится до 512 ГБ и даже 1 ТБ.
Создаем виртуального помощника с помощью python
https://morioh.com/p/de131ece98ec?f=5c21fb01c16e2556b555ab32
https://morioh.com/p/de131ece98ec?f=5c21fb01c16e2556b555ab32
Morioh
How To Build A Virtual Assistant Using Python
In this article will show you how to build your own virtual assistant using the Python Programming Language! A virtual assistant is an application that can understand voice commands and complete tasks for a user. Google’s assistant and Amazon’s Alexa are…
Представляем Numba: высокопроизводительный компилятор Python
https://morioh.com/p/ea62e7fb53da?f=5c21fb01c16e2556b555ab32
https://morioh.com/p/ea62e7fb53da?f=5c21fb01c16e2556b555ab32
Morioh
Introducing Numba: A High Performance Python Compiler
Обработка текстов на естественном языке (Natural Language Processing, NLP) — крайне важная задача в области искусственного интеллекта. Успешная реализация делает возможными такие продукты, как Alexa от Amazon и Google Translate. Эта книга поможет вам изучить PyTorch — библиотеку глубокого обучения для языка Python — один из ведущих инструментов для дата-сайентистов и разработчиков ПО, занимающихся NLP.
Делип Рао и Брайан Макмахан введут вас в курс дел с NLP и алгоритмами глубокого обучения. И покажут, как PyTorch позволяет реализовать приложения, использующие анализ текста.
В этой книге
• Вычислительные графы и парадигма обучения с учителем.
• Основы оптимизированной библиотеки PyTorch для работы с тензорами.
• Обзор традиционных понятий и методов NLP.
• Упреждающие нейронные сети (многослойный перцептрон и другие).
• Улучшение RNN при помощи долгой краткосрочной памяти (LSTM) и управляемых рекуррентных блоков
• Предсказание и модели преобразования последовательностей.
• Паттерны проектирования NLP-систем
Делип Рао и Брайан Макмахан введут вас в курс дел с NLP и алгоритмами глубокого обучения. И покажут, как PyTorch позволяет реализовать приложения, использующие анализ текста.
В этой книге
• Вычислительные графы и парадигма обучения с учителем.
• Основы оптимизированной библиотеки PyTorch для работы с тензорами.
• Обзор традиционных понятий и методов NLP.
• Упреждающие нейронные сети (многослойный перцептрон и другие).
• Улучшение RNN при помощи долгой краткосрочной памяти (LSTM) и управляемых рекуррентных блоков
• Предсказание и модели преобразования последовательностей.
• Паттерны проектирования NLP-систем
Доброго времени суток уважаемые подписчики канала, хотел согласовать с вами один вопрос, стоит ли изменить название данного комъюнити?
Anonymous Poll
40%
Да
60%
Нет
Профессиональная конференция для Python-разработчиков
27 марта 2020 Москва, Инфопространство
https://conf.python.ru/moscow/2020/?utm_source=vk&utm_medium=cpc&utm_campaign=1014062068&utm_content=64521132&utmstat=us%7Cvk%7Ccid%7C1014062068%7Caid%7C64521132
27 марта 2020 Москва, Инфопространство
https://conf.python.ru/moscow/2020/?utm_source=vk&utm_medium=cpc&utm_campaign=1014062068&utm_content=64521132&utmstat=us%7Cvk%7Ccid%7C1014062068%7Caid%7C64521132
conf.python.ru
Профессиональная конференция для Python-разработчиков 2020
Это неделя уникального профессионального общения в форматах: мастер-классов, круглых столов, битв с Go и PHP, интервью, консультаций и анонимных признаний в провалах.