Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа со списком объектов в многопоточном приложении
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Программирование
kosyak©
Не занл в какой раздел запостить - написал сюда.
В приложении есть список динамических объектов. Объекты из этого списка пользуют несколько потоков для чтения/записи. Так же сами объекты могут быть удалены (список очищен).
Как идеологически правильно организовать работу с атким списком?
Какие объекты синхронизации стоит использовать?
Cosmojam
mutex?
kosyak©
Сейчас есть мютекс на доступ к списку, и мютекс на каждый объект списка...
Но что-то я никак не могу правильно расставить все блокировки.

Вот например

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

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

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

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

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

где бы почитать про примеры реализации таких объектов синхронизации на основе стандартного набора (mutex, semaphor,...)?
Demeny
Цитата(kosyak© @ Feb 26 2012, 13:18) *
Печально..
Как бы так реализовать "волшебный" мютекс...

Всего-навсего надо отказаться от удаления объектов в соседнем потоке, а заменить его на изменение статуса, например, "удалён". А объекты со статусом "удалён" собирать и удалять физически каким-то отдельным образом, периодически, либо "сборщиком мусора", либо в том же потоке, который работает со счётчиками.
Как-то так.
Olej
Цитата(kosyak© @ Feb 26 2012, 08:36) *
Как идеологически правильно организовать работу с атким списком?
Какие объекты синхронизации стоит использовать?

вообще то, обычная и повсеместная практика (ядро Linux) для такой задачи - rw-блокировки, на всю списковую структуру.
в некоторых случаях это может создавать неприятности (огромные задержки по модификации при плотных обращениях читателей) - тогда используют сериальные блокировки (например <linux/seqlock.h>), это хороший вариант.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.