Я хотел бы знать, являются ли встроенные контейнеры Python (список, вектор, набор...) потокобезопасными? Или мне нужно реализовать среду блокировки/разблокировки для моей общей переменной?
Являются ли Python встроенными контейнерами потокобезопасными?
Ответ 1
Вам нужно реализовать свою собственную блокировку для всех общих переменных, которые будут изменены в Python. Вам не нужно беспокоиться о чтении из переменных, которые не будут изменены (т.е. Параллельные чтения в порядке), поэтому неизменяемые типы (frozenset
, tuple
, str
), вероятно, безопасны, но это не будет "Больно. Для вещей, которые вы собираетесь менять - list
, set
, dict
и большинства других объектов, вы должны иметь свой собственный механизм блокировки (в то время как операции на месте в порядке на большинстве из них, потоки могут привести к супер-неприятным ошибкам - вы можете также реализовать блокировку, это довольно легко).
Кстати, я не знаю, знаете ли вы это, но в Python очень легко блокировать - создать объект threading.lock, а затем вы можете его получить/отпустить следующим образом:
import threading
list1Lock = threading.Lock()
with list1Lock:
# change or read from the list here
# continue doing other stuff (the lock is released when you leave the with block)
В Python 2.5 выполните from __future__ import with_statement
; Python 2.4 и до этого не имеют этого, поэтому вы хотите поместить вызовы purchase()/release() в try:...finally:
блоки:
import threading
list1Lock = threading.Lock()
try:
list1Lock.acquire()
# change or read from the list here
finally:
list1Lock.release()
# continue doing other stuff (the lock is released when you leave the with block)
Некоторая очень хорошая информация о синхронизации потоков в Python.
Ответ 2
Да, но вам все равно нужно быть осторожным.
Например:
Если два потока участвуют в pop()
из списка только с одним элементом, один поток получит элемент успешно, а другой получит IndexError
Код, подобный этому, не является потокобезопасным
if L:
item=L.pop() # L might be empty by the time this line gets executed
Вы должны написать так:
try:
item=L.pop()
except IndexError:
# No items left
Ответ 3
Они потокобезопасны, если вы не отключите GIL в коде C для потока.