Уведомления

Группа в Telegram: @pythonsu

#1 Март 22, 2019 08:58:30

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

потокобезопасность словаря

Как я понял ситуацию
1) словарь потокобезопасен с точки зрения чтения и записи. Это означает что при многопоточном приложении, не возникнет никаких ошибок при множественном доступе на чтение или запись (имеется ввиду с явным указанием ключа).
2) словарь не потокобезопасен с точки зрения предсказуемости результата и/или эффекта “гонки данных”. Это означает что
в коде

 if param in super_dict :  # дествие 1
        ... что-то сделать   # действие 2
между действиями 1 и 2 в процессе выполнения одного потока нету гарантий что словарь не изменится. Наверное типичный пример если между этими действиями в другом потоке произойдет удаление данного ключа словаря. Тогда действие 2, расчитывающее на его наличие вероятнее всего сделает что то что породит исключение KeyError

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



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#2 Март 22, 2019 10:25:46

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

потокобезопасность словаря

> не возникнет никаких ошибок при множественном доступе на чтение или запись (имеется ввиду с явным указанием ключа).

Конечно же не всё так хорошо. Вот пример кода только с чтением и записью в котором будет возникать ошибки:

 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()



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#3 Март 22, 2019 11:01:56

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

потокобезопасность словаря

ну это не тот пример и не так ошибка. Она воспроизводится в 1 поточоном коде. Здесь же итерация по словарю который изменяфет размер. Это то о чем упоминал автор в первом посте.
сделай пример без итерации



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#4 Март 22, 2019 11:14:07

Striver
От:
Зарегистрирован: 2006-10-26
Сообщения: 247
Репутация: +  22  -
Профиль   Отправить e-mail  

потокобезопасность словаря

Ох ты! Да тут дискуссия нарисовалась.
Спасибо всем ответившим!

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

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



Офлайн

#5 Март 22, 2019 11:25:27

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

потокобезопасность словаря

> ну это не тот пример и не так ошибка. Она воспроизводится в 1 поточоном коде

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

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

Не в итерации дело, а в том что если шарить изменяемое состояние между потоками, то рано или поздно начнутся проблемы. Как выход из ситуации можно использовать блокировки. Но если эти блокировки применить к моему примеру, то код фактически станет однопоточным…



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Отредактировано Rodegast (Март 22, 2019 11:27:08)

Офлайн

#6 Март 23, 2019 12:26:06

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

потокобезопасность словаря

Мда. Ты как обычно. С тобой конструктивный диалог вести вообще проблемно. Я уже говорил что как то не буду. Но видимо сам себя обманул.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#7 Март 23, 2019 13:06:38

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

потокобезопасность словаря

> С тобой конструктивный диалог вести вообще проблемно.

Совершенно верно. Я обычно говорю о вполне очевидных вещах, по этому отрицать их действительно проблемно…



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#8 Апрель 18, 2019 20:13:26

teddy_coder
Зарегистрирован: 2018-10-01
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

потокобезопасность словаря

Может исопользование объекта 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)

Офлайн

#9 Апрель 24, 2019 12:44:02

Quark
Зарегистрирован: 2019-03-01
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

потокобезопасность словаря

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

Офлайн

#10 Апрель 24, 2019 13:13:07

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

потокобезопасность словаря

Quark
Это как по вашему будет выглядеть? Приведите пример



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version