Есть std::list<...>.
К нему обращаются несколько потоков на чтение и один на модификацию (добавление-удаление).
Задача:
- потоки на чтения друг друга блокировать не должны, но должны блокировать поток модификации.
- если поток модификации начал обработку списка, то должны блокироваться потоки чтения.
У меня пока одна версия как это сделать.
Завести два мьютекса: mutexRead и mutexWrite.
Поток модификации просто запирает (или блокируется) оба мьютекса последовательно - или заблокируется на одном из них или заблокирует потоки чтения на muteWrite.
Потоки чтения тоже работают с двумя мьютексами, но по другому:
- запирают mutexWrite без блокировки (trylock). Если он уже был заперт, то лочатся на нём (типа, лист модифицируется). После разблокирования потока - делают свои дела со списком и разлочат mutexWrite.
- запирают mutexRead без блокировки (trylock). Делают свои дела со списком. Если mutexRead не был заперт на входе, то отпирают.
Тяжело читать да? Какое-то некрасивое решение, громоздко... Короче не нравится мне.
Может кто-то другое посоветует по мотивам первого абзаца (условие задачи)?
Синхронизация доступа к std::list<> (Требуется совет братиев во программировании :))
Модератор: Модераторы разделов
-
oav
- Бывший модератор
- Сообщения: 296
Re: Синхронизация доступа к std::list<>
Могу дать рихторовский класс где весьма неплохо реализована задача Single writer multiple reader guard. Только он для Win32 но переделать не составит труда.
-
Zeus
- Сообщения: 694
Re: Синхронизация доступа к std::list<>
А что он их себя представляет?
Хотя ладно, давай зашли на z e u s АУ-АУ crtc. spb. ru
Посмотрю что там.
Спасибо.
-
oav
- Бывший модератор
- Сообщения: 296
Re: Синхронизация доступа к std::list<>
-
v04bvs
- Сообщения: 636
- ОС: Debian GNU/Linux
Re: Синхронизация доступа к std::list<>
Zeus писал(а): ↑03.02.2006 10:56Есть std::list<...>.
К нему обращаются несколько потоков на чтение и один на модификацию (добавление-удаление).
Задача:
- потоки на чтения друг друга блокировать не должны, но должны блокировать поток модификации.
- если поток модификации начал обработку списка, то должны блокироваться потоки чтения.
У меня пока одна версия как это сделать.
Завести два мьютекса: mutexRead и mutexWrite.
Поток модификации просто запирает (или блокируется) оба мьютекса последовательно - или заблокируется на одном из них или заблокирует потоки чтения на muteWrite.
Потоки чтения тоже работают с двумя мьютексами, но по другому:
- запирают mutexWrite без блокировки (trylock). Если он уже был заперт, то лочатся на нём (типа, лист модифицируется). После разблокирования потока - делают свои дела со списком и разлочат mutexWrite.
- запирают mutexRead без блокировки (trylock). Делают свои дела со списком. Если mutexRead не был заперт на входе, то отпирают.
Тяжело читать да? Какое-то некрасивое решение, громоздко... Короче не нравится мне.
Может кто-то другое посоветует по мотивам первого абзаца (условие задачи)?
Это классическая задача синхронизации, поищите в сети алгоритм. Если надо - я попробую написать.
-
Zeus
- Сообщения: 694
Re: Синхронизация доступа к std::list<>
Да мне алгоритм не нужен - хватит и ИДЕИ. Красивой только, идеи. А уж реализовать-то - дело техники.
Может у кого есть оригинальное решение (классическое/неклассическое - неважно), описываемое парой предложений.
-
v04bvs
- Сообщения: 636
- ОС: Debian GNU/Linux
Re: Синхронизация доступа к std::list<>
В общем алгоритм на псевдоСи, использует общие семафоры и одну общую переменную.
int rc = 0; //количество читателей
semaphore sw = 1; //семафор на запись
semaphore st = 1; //вспомогательный семафор
down, up - опустить, поднять семафор.
Используя SystemV IPC можно обойтись и без дополнительной общей переменной (думаю понятно, как это сделать).
У этого алгоритма есть один недостаток - писатель не получит доступа к ресурсу до того момента, пока все читатели не освободят ресурс.
int rc = 0; //количество читателей
semaphore sw = 1; //семафор на запись
semaphore st = 1; //вспомогательный семафор
Код: Выделить всё
//читатель
void reader( )
{
// цикл чтения
while( 1 ) {
// входим в блок чтения
down(&st);
if( rc++ == 0 ) //если это первый процесс-читатель
down(&sw); // запрещаем запись (или ждём пока писатель освободит семафор)
up(&st);
do_read_operation(); //производим все необходимые действия
// выходим из блока чтения
down(&st);
if( --rc == 0 ) //если это последний процесс-читатель
up(&sw);
up(&st);
}
}
// писатель
void writer( )
{
while( 1 ) {
down(&sw);
do_write_operation();
up(&sw);
}
}down, up - опустить, поднять семафор.
Используя SystemV IPC можно обойтись и без дополнительной общей переменной (думаю понятно, как это сделать).
У этого алгоритма есть один недостаток - писатель не получит доступа к ресурсу до того момента, пока все читатели не освободят ресурс.
-
Zeus
- Сообщения: 694
Re: Синхронизация доступа к std::list<>
oav - спасибо, класс получил. До подробного изучения руки ещё не дошли, но мельком посмотрел - сильно похоже на то, что написал v04bvs.
Это существенный недостаток.
У меня-то потоки равноправные: "кто первый встал - того и тапки", но нужно, чтобы потоки чтения друг друга не блокировали.
У этого алгоритма есть один недостаток - писатель не получит доступа к ресурсу до того момента, пока все читатели не освободят ресурс.
Это существенный недостаток.
У меня-то потоки равноправные: "кто первый встал - того и тапки", но нужно, чтобы потоки чтения друг друга не блокировали.
-
Zeus
- Сообщения: 694
Re: Синхронизация доступа к std::list<>
Короче, написал класс "по мотивам" постов и присланных файликов:
счётчики читателей-писателей, мьютекс и семафор.
Всем спасибо.
счётчики читателей-писателей, мьютекс и семафор.
Всем спасибо.