2011-01-20 2 views
6

Я читал о GIL, и он никогда не задавался, если это включает в себя основной поток или нет (я так полагаю). Причина, о которой я прошу, заключается в том, что у меня есть программа с настройками потоков, которые изменяют словарь. Основной поток добавляет/удаляет на основе ввода проигрывателя, в то время как поток выполняет цикл обновления данных и изменения данных.Python threading и GIL

Однако в некоторых случаях поток может перебирать ключи словаря, где их можно было бы удалить. Если есть так называемый GIL, и они запускаются последовательно, почему я получаю dict измененные ошибки? Если только один предполагается запустить одновременно, то технически это не должно происходить.

Может ли кто-нибудь пролить свет на такую ​​вещь? Спасибо.

+2

Как правило, потоки Python имеют смысл только для потоков, связанных с I/O. Если вам требуется согласованность доступа к структурам данных параллельно, вам нужна явная блокировка. Если вам нужен параллелизм, связанный с процессором, обычно вам нужно использовать что-то совершенно другое. – 9000

ответ

4

GIL блокируется на уровне байтового кода Python и применяется ко всем потокам, даже к основному потоку. Если у вас есть один поток, изменяющий словарь, и другие итерирующие ключи, они будут мешать друг другу.

«Только один работает за один раз» - это правда, но вы должны понимать единицу детализации. В случае GIL CPython гранулярность является инструкцией байт-кода, поэтому выполнение может переключаться между потоками в любом байт-коде.

+0

из страницы глоссария Python 'GIL Механизм, используемый интерпретатором CPython, чтобы гарантировать, что только один поток выполняет байт-код Python за раз. Это упрощает реализацию CPython, делая объектную модель (включая критические встроенные типы, такие как dict), неявно защищенной от одновременного доступа. «Если я не ошибаюсь, это означает, что dict является потокобезопасным? – boh

+1

Это зависит от операций, которые вы выполняете на dict. Это не является потокобезопасным: 'd [k] + = 1'. Если у вас есть сомнения, используйте собственную синхронизацию. –

10

Они работает в то же время, они просто не выполнять одновременно. Итерации могут чередоваться. Цитата Python:

Механизм, используемый интерпретатором CPython, чтобы гарантировать, что только один поток выполняет Python байткод в то время.

Так два for циклы могут запускать в то же время, не будет просто нет (к примеру) два del dict[index] «s одновременно.

+0

Ах спасибо, это имеет смысл для меня. – Charles

+1

Тогда вы должны отметить ответ как принято :) –

3

Гиль предотвращает одновременное изменение состояния интерпретатора двумя потоками. Он не предоставляет никаких ограничений последовательности потоков или любого вида мьютекса вообще по степени детализации, меньшей, чем весь процесс. Если вам нужно прочитать и изменить dict в двух потоках, вы должны использовать мьютекс

1

Python переключает потоки чаще, чем вы, кажется, думает, что это так. Вы говорите, что «только один» должен работать одновременно, и технически это правда, но это зависит от вашего определения «один». Атомные операции Питона очень малы. Например: добавление одного слова в словарь. Итерация по всему словарю может быть прервана.

Вы должны использовать объект блокировки из библиотеки threading, чтобы изолировать атомные операции вашей программы.

Смежные вопросы