Найти - Пользователи
Полная версия: потокобезопасность словаря
Начало » Python для экспертов » потокобезопасность словаря
1 2 3
JOHN_16
Как я понял ситуацию
1) словарь потокобезопасен с точки зрения чтения и записи. Это означает что при многопоточном приложении, не возникнет никаких ошибок при множественном доступе на чтение или запись (имеется ввиду с явным указанием ключа).
2) словарь не потокобезопасен с точки зрения предсказуемости результата и/или эффекта “гонки данных”. Это означает что
в коде
 if param in super_dict :  # дествие 1
        ... что-то сделать   # действие 2
между действиями 1 и 2 в процессе выполнения одного потока нету гарантий что словарь не изменится. Наверное типичный пример если между этими действиями в другом потоке произойдет удаление данного ключа словаря. Тогда действие 2, расчитывающее на его наличие вероятнее всего сделает что то что породит исключение KeyError

Выход из ситуации вам предложили - взять реализацию словаря с блокировками. Я не вижу ничего в этом зазорного. Эт овсе ранво будет гораздо быстрее если вы возьмете внешнее решение.
Rodegast
> не возникнет никаких ошибок при множественном доступе на чтение или запись (имеется ввиду с явным указанием ключа).

Конечно же не всё так хорошо. Вот пример кода только с чтением и записью в котором будет возникать ошибки:
 from threading import Thread
 
S = {x: x*2 for x in range(1000)}
 
def p1():
	for x in range(1000):
		S[x*2] = x
 
def p2():
	for x in S:
		print(S[x])
 
potok1 = Thread(target=p1)
potok2 = Thread(target=p2)
potok2.start()
potok1.start()
JOHN_16
ну это не тот пример и не так ошибка. Она воспроизводится в 1 поточоном коде. Здесь же итерация по словарю который изменяфет размер. Это то о чем упоминал автор в первом посте.
сделай пример без итерации
Striver
Ох ты! Да тут дискуссия нарисовалась.
Спасибо всем ответившим!

Почитал про словарь с блокировками в книге. Наверное, так и буду делать.

>Конечно же не всё так хорошо. Вот пример кода только с чтением и записью в котором будет возникать ошибки:
>…
Это, всё-таки случай итераций по самому словарю (функция p2). В моём случае это было не нужно.
Rodegast
> ну это не тот пример и не так ошибка. Она воспроизводится в 1 поточоном коде

Нет. В однопоточном коде словарь не изменит своего размера во время итерации и всё будет хорошо.

> сделай пример без итерации

Не в итерации дело, а в том что если шарить изменяемое состояние между потоками, то рано или поздно начнутся проблемы. Как выход из ситуации можно использовать блокировки. Но если эти блокировки применить к моему примеру, то код фактически станет однопоточным…
JOHN_16
Мда. Ты как обычно. С тобой конструктивный диалог вести вообще проблемно. Я уже говорил что как то не буду. Но видимо сам себя обманул.
Rodegast
> С тобой конструктивный диалог вести вообще проблемно.

Совершенно верно. Я обычно говорю о вполне очевидных вещах, по этому отрицать их действительно проблемно…
teddy_coder
Может исопользование объекта Lock поможет?

 from multiprocessing import Lock
...
lock = Lock()
...
lock.acquire()
# что-то делаем со словарём dict или любыми другими общими данными
lock.release()
...
Подробнее: https://docs.python.org/3.6/library/multiprocessing.html#synchronization-between-processes

Хотя, кончено,лучше через специально для этого предназначенную очередь (Queue)
Quark
GIL насколько понимаю гарантирует только, что сам Python не упадет,
а на пользовательские данные без разницы.
JOHN_16
Quark
Это как по вашему будет выглядеть? Приведите пример
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB