Перейти к содержанию
    

Работа со списком объектов в многопоточном приложении

Не занл в какой раздел запостить - написал сюда.

В приложении есть список динамических объектов. Объекты из этого списка пользуют несколько потоков для чтения/записи. Так же сами объекты могут быть удалены (список очищен).

Как идеологически правильно организовать работу с атким списком?

Какие объекты синхронизации стоит использовать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сейчас есть мютекс на доступ к списку, и мютекс на каждый объект списка...

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

 

Вот например

 

Пройти по всем объектам и уменьшить счетчик:

Блокируем список

Берем элемент

Блокируем его

уменьшаем счетчик

разблокируем элдемент

переходим к следующему

Разблокируем список

 

Т.е. если вызывать эту процедуру из разных потоков, то они будут ждать разблокировки всего списка, хотя эта процедура не изменяет сам список и эта блокировка вроде как излишня...но в то же время Процедура очистки списка обязана блокировать весь список на время своей работы..т.е. пиходится блокировать спсиок всегда... Или есть еще какие метОды синхронизации???

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. если вызывать эту процедуру из разных потоков, то они будут ждать разблокировки всего списка, хотя эта процедура не изменяет сам список и эта блокировка вроде как излишня...но в то же время Процедура очистки списка обязана блокировать весь список на время своей работы..т.е. пиходится блокировать спсиок всегда...

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Печально..

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

 

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

read_unlock -

 

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

write_unlock

 

где бы почитать про примеры реализации таких объектов синхронизации на основе стандартного набора (mutex, semaphor,...)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Печально..

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

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

Как-то так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как идеологически правильно организовать работу с атким списком?

Какие объекты синхронизации стоит использовать?

вообще то, обычная и повсеместная практика (ядро Linux) для такой задачи - rw-блокировки, на всю списковую структуру.

в некоторых случаях это может создавать неприятности (огромные задержки по модификации при плотных обращениях читателей) - тогда используют сериальные блокировки (например <linux/seqlock.h>), это хороший вариант.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...