2010-08-23 3 views
19

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

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

ответ

17

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

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

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

+2

Даже в CPython доступ к словарю не является атомарным при любых обстоятельствах. Если функции хэша/сравнения ключей написаны на Python, GIL будет временно освобожден между кодами операций, когда эти функции выполняются. (Вероятно, вы уже знаете это, но я считаю, что стоит обратить внимание на других читателей) –

+1

Спасибо! Я всю ночь узнал о GIL. Очевидно, что (C) программирование на Python будет включать другой способ взглянуть на потоки, чем я привык. @ Daniel Stutzbach: Я новичок в Python и не обратил бы внимания на этот факт. Спасибо. – philo

+3

@philo, суммируя ситуацию многозадачности для CPython: потоки помогут вам, только если у вас есть ожидания ввода/вывода (которые вы можете делегировать потоку) или тяжелых операций, выполняемых в потоковом расширении Python (например, 'numpy '). Если ваша цель заключается в использовании нескольких ядер для Python-кодированных операций с привязкой к процессору, используйте 'multiprocessing' вместо' threading'. –

1
+0

Что это связано с вопросом? – habnabit

+0

Это означает, что не так много многопоточных вещей, о которых нужно беспокоиться, так как они обмениваются данными в интерпретаторе. –

+0

@KevinKostlan это не совсем так. GIL позволяет использовать чистый код python для запуска в одном потоке за раз. распространенной ошибкой считать python как однопоточный процесс, но он использует реальные потоки. это значит, что даже если глобальная блокировка позволяет работать только по одному потоку, это действительно правильный аргумент, чтобы задать вопрос о том, отражается ли выделение памяти в одном потоке на других. btw, операции ввода/вывода, такие как socket.send и т. Д., Получают бесплатный билет от GIL - таким образом, у вас есть несколько потоков, работающих и работающих вместе. – RoeeK