реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Работа со списком объектов в многопоточном приложении
kosyak©
сообщение Feb 26 2012, 05:36
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966



Не занл в какой раздел запостить - написал сюда.
В приложении есть список динамических объектов. Объекты из этого списка пользуют несколько потоков для чтения/записи. Так же сами объекты могут быть удалены (список очищен).
Как идеологически правильно организовать работу с атким списком?
Какие объекты синхронизации стоит использовать?
Go to the top of the page
 
+Quote Post
Cosmojam
сообщение Feb 26 2012, 06:25
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182



mutex?


--------------------
typedef enum { no, yes, maybe } bool; | блог тут
Go to the top of the page
 
+Quote Post
kosyak©
сообщение Feb 26 2012, 07:00
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966



Сейчас есть мютекс на доступ к списку, и мютекс на каждый объект списка...
Но что-то я никак не могу правильно расставить все блокировки.

Вот например

Пройти по всем объектам и уменьшить счетчик:
Блокируем список
Берем элемент
Блокируем его
уменьшаем счетчик
разблокируем элдемент
переходим к следующему
Разблокируем список

Т.е. если вызывать эту процедуру из разных потоков, то они будут ждать разблокировки всего списка, хотя эта процедура не изменяет сам список и эта блокировка вроде как излишня...но в то же время Процедура очистки списка обязана блокировать весь список на время своей работы..т.е. пиходится блокировать спсиок всегда... Или есть еще какие метОды синхронизации???
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 26 2012, 07:38
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(kosyak© @ Feb 26 2012, 10:00) *
Т.е. если вызывать эту процедуру из разных потоков, то они будут ждать разблокировки всего списка, хотя эта процедура не изменяет сам список и эта блокировка вроде как излишня...но в то же время Процедура очистки списка обязана блокировать весь список на время своей работы..т.е. пиходится блокировать спсиок всегда...

Если не хотите блокировать весь список - нужно внимательно смотреть, чтобы между операциями "берём элемент" (то бишь получаем указатель на него), "блокируем его", "уменьшаем счётчик", "разблокируем его" не могло вклиниться удаление элемента из соседнего потока, в противном случае взятый указатель уже будет недействительным и произойдет exception. Чтобы этого не произошло - элемент нужно блокировать ДО получения на него указателя, и соседний поток тоже должен блокировать элемент ДО его удаления. Это неразрешимая ситуация, мютекс блокировки обычно находится внутри самого элемента, и чтобы его блокировать, нужно уже знать указатель ... Вынесение мютекса в статический массив тоже ничего не решит - всё равно внутри элемента нужно будет хранить индекс мютекса в массиве и т. д.
Поэтому, по всей видимости, без блокировки всего списка не обойтись.


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
kosyak©
сообщение Feb 26 2012, 10:18
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966



Печально..
Как бы так реализовать "волшебный" мютекс...

read_lock - блокирует объект на чтение (в первом приближении счетчик)
read_unlock -

write_lock - ждет когда отработают все read_lock'и (счетчик 0 ) и блокирует объект вообще на все.
write_unlock

где бы почитать про примеры реализации таких объектов синхронизации на основе стандартного набора (mutex, semaphor,...)?
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 26 2012, 11:15
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(kosyak© @ Feb 26 2012, 13:18) *
Печально..
Как бы так реализовать "волшебный" мютекс...

Всего-навсего надо отказаться от удаления объектов в соседнем потоке, а заменить его на изменение статуса, например, "удалён". А объекты со статусом "удалён" собирать и удалять физически каким-то отдельным образом, периодически, либо "сборщиком мусора", либо в том же потоке, который работает со счётчиками.
Как-то так.


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
Olej
сообщение Feb 29 2012, 10:21
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458



Цитата(kosyak© @ Feb 26 2012, 08:36) *
Как идеологически правильно организовать работу с атким списком?
Какие объекты синхронизации стоит использовать?

вообще то, обычная и повсеместная практика (ядро Linux) для такой задачи - rw-блокировки, на всю списковую структуру.
в некоторых случаях это может создавать неприятности (огромные задержки по модификации при плотных обращениях читателей) - тогда используют сериальные блокировки (например <linux/seqlock.h>), это хороший вариант.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 10th July 2025 - 15:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01399 секунд с 7
ELECTRONIX ©2004-2016