многопоточность python: модель памяти и видимость

Выявляет ли многопоточность python проблемы видимости памяти и переупорядочения операторов, как это делает Java? Поскольку я не могу найти никаких ссылок на «Модель памяти Python» или что-то в этом роде, несмотря на то, что многие люди пишут многопоточный код Python, я предполагаю, что этих ошибок здесь не существует. Например, нет ключевого слова volatile. Но, похоже, нигде явно не указано, что, например, изменение переменной в одном потоке сразу видно всем другим потокам.

Может быть, все это очевидно для программистов на Python, но мне, как напуганному Java-программисту, требуется дополнительное подтверждение :)


person philo    schedule 23.08.2010    source источник


Ответы (1)


Для Python не существует формальной модели многопоточности (в конце концов, для Java не было ее годами... надеюсь, в конечном итоге она будет написана и для Python).

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

В частности, CPython, как упоминал @Rawheiser, использует глобальную блокировку интерпретатора; другие реализации (PyPy, IronPython, Jython, ...) этого не делают (поэтому они могут эффективно использовать несколько ядер с моделью потоков, в то время как CPython требует многопроцессорной обработки для той же цели), поэтому вам не следует рассчитывать на это, если вы хотите для написания кода, переносимого во все реализации Python. (Таким образом, вы не должны рассчитывать на «атомарность» операций, которые в CPython являются атомарными только из-за GIL, таких как доступ к словарю — в других реализациях Python несколько потоков могут изменять dict одновременно и вызывать ошибки, если только вы не защитите диктовку блокировкой и т.п.).

person Alex Martelli    schedule 23.08.2010
comment
Даже в CPython доступ к словарю не является атомарным при любых обстоятельствах. Если функции хеширования/сравнения ключей написаны на Python, GIL будет временно освобождаться между кодами операций, когда эти функции выполняются. (Возможно, вы уже знаете это, но я думаю, что это стоит указать другим читателям) - person Daniel Stutzbach; 23.08.2010
comment
Спасибо! Я провел все свое утро, изучая GIL. Очевидно, что программирование (C)Python будет включать в себя другой взгляд на потоки, чем я привык. @Daniel Stutzbach: я новичок в Python и пропустил бы этот факт. Спасибо. - person philo; 23.08.2010
comment
@philo, резюмируя ситуацию с многозадачностью для CPython: потоки помогут вам, только если у вас есть ожидания ввода-вывода (которые вы можете делегировать потоку) или тяжелые операции, выполняемые в потокобезопасном расширении Python (например, numpy). Если ваша цель состоит в том, чтобы использовать несколько ядер для кодированных на Python операций, связанных с процессором, используйте multiprocessing вместо threading. - person Alex Martelli; 23.08.2010
comment
@AlexMartelli, ваш ответ все еще действителен? - person ; 15.05.2016