2010-01-28 2 views
4

В python у меня есть глобальная переменная, которая получает чтение/приращение различными потоками. Из-за GIL это может вызвать проблемы без использования каких-либо механизмов блокировки?Python GIL и globals

+0

Вы говорите о реализации с использованием модуля «threading»? В этом случае вы должны использовать предоставленный механизм блокировки: см. Http://docs.python.org/library/threading.html – avpx

ответ

3

Да, многопоточность без блокировки почти всегда вызывает проблемы, с или без GIL.

+2

Обратите внимание, что GIL не существует для защиты ваших данных приложения; это только для защиты некоторых внутренних структур Python, таких как подсчет ссылок для объектов Python. Вы все равно должны заблокировать свои структуры. –

+1

Точно. GIL защищает Python от себя, но он не делает ничего, чтобы защитить вас. –

+1

И, конечно, подавляющее большинство двигателей исполнения Python даже не имеют * GIL. –

6

В GIL требуется, чтобы интерпретатор полностью выполнял одну инструкцию по байт-коду перед тем, как другой поток может взять верх. Однако нет оснований предполагать, что операция приращения является одной инструкцией. Например:

>>> import dis 
>>> dis.dis(compile("x=753","","exec")) 
    1   0 LOAD_CONST    0 (753) 
       3 STORE_NAME    0 (x) 
       6 LOAD_CONST    1 (None) 
       9 RETURN_VALUE 
>>> dis.dis(compile("x+=1","","exec")) 
    1   0 LOAD_NAME    0 (x) 
       3 LOAD_CONST    0 (1) 
       6 INPLACE_ADD 
       7 STORE_NAME    0 (x) 
      10 LOAD_CONST    1 (None) 
      13 RETURN_VALUE 

Как вы можете видеть, даже эти простые операции являются более чем одной инструкцией байткода. Поэтому, когда вы используете обмен данными между потоками, вы должны использовать с помощью отдельного механизма блокировки (например, threading.lock) для обеспечения согласованности данных.

+2

Ouch. Я имею в виду, 3 upvotes и никто не заметил вывод 'dis.dis (« x = 753 »)'? Я исправил код. – tzot

+0

Вот пример, где я должен уделять больше внимания тому, что я пишу - спасибо :). Кроме того, он отображает точку еще более четко - после загрузки значения есть несколько инструкций до того, как значение будет сохранено снова. –

+0

это даже не 100% правда. Байт-код (почти любой) может фактически вызвать больше кода на основе python, используя '__getitem__' или' __add__' или любой другой сценарий. Затем вы заканчиваете тем, что потоки меняются в середине через один байт-код. – fijal

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

  • Нет связанных вопросов^_^