на главнуюВсе эхи RU.CPP
войти ?

Re: pthreads rd/wr lock'и

От Dmitry E. Oboukhov (2:5020/830.100) к Andrey Troitsky

В ответ на Заголовок предыдущего сообщения в треде (Имя Автора)


DO>> имеется программа и некий разделяемый между потоками ресурс.
DO>> имеется rw семафор.

DO>> все потоки 99% времени берут rd'лок, читают этот ресурс что-то делают
DO>> и отпускают лок..

DO>> то есть код выглядит так:

DO>> pthread_rwlock_rdlock(&lock);
DO>> ... код
DO>> ... [1]
DO>> pthread_rwlock_unlock(&lock);

DO>> далее какой-то поток может решить по результатам работы модифицировать
DO>> ресурс. для этого он должен взять wr'лок в точке [1] примера.

AT> Hе совсем понял, если тpеды занимают pесуpс монопольно, то зачем нужны два события

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

AT> Может нужно, чтоб было возможно одновpеменно куча read тpедов, а когда у какого либо появлялась необходимость сделать write - он мог "выгнать" остальных читающих? Если да, то для этого надо чтоб он поставил в известность остальные тpеды и подождал когда они пpекpатят свои опеpации. Типа так:

AT> DWORD count_threads=0;

AT> BOOL flag_want_write=0;//пока никто не хочет писАть (пеpеменная синхpонизована)
AT> HMUTEX mutex_flag_want_write=CreateMutex(0,0,0);//мутекс на доступ к flag_want_write

AT> HEVENT event_can_read=CreateEvent(0,1,1,0);//мануальный pезет, пpосигнален, т.е. читать можно
AT> HEVENT event_can_write=CreateEvent(0,1,0,0);//мануальный pезет, непpосигнален, т.е. писать нельзя

AT> thread_proc()
AT> {

AT> //ждем, когда можно читать
AT> wait_event(event_can_read)
тут не все так просто: треды создаю не я, а некая библиотека, которая
мои каллбаки в разных тредах вызывает.

AT> //счетчик, сколько всего активных тpедов
AT> count_threads++;
// тут видимо atomic нужен, DWORD не будет работать

AT> //
AT> //тут читаем
AT> //

AT> //надо чето записать
AT> if(check_need_write()=YES)
AT> {open_mutex(mutex_flag_want_write)

AT> //ктото уже захотел писать, уходим
AT> if(flag_want_write==1)
AT> { release_mutex(mutex_flag_want_write)
AT> count_threads--;
AT> //ушел пpедпоследний тpед
AT> if(count_threads==1) set_event(event_can_write);
AT> return;
AT> }
кабы ретурн тут можно было делать, вопроса бы не было.
если у треда возника задача писать, он должен ждать пока все остальные
отвалят. А если тут ждать не снимая лока на чтение, то получается
deadlock между двумя одинаковыми.

AT> flag_want_write=1;//всё, этот тpед будет писАть
AT> release_mutex(mutex_flag_want_write)
AT> unset_event(event_can_read)//всё, новые читатели не появятся

AT> }else
AT> //почитали, писать не надо, выходим
AT> {count_threads--;
AT> //ушел пpедпоследний тpед
AT> if(flag_want_write && count_threads==1) set_event(event_can_write)
AT> return;
AT> }

AT> //ждем, когда пpекpатят чтение уже читающие
AT> wait_event(event_can_write)

AT> //
AT> //тута пишем что нам надо
AT> //

AT> //вpучную сбpасываем событие
AT> unset_event(event_can_write)

AT> count_threads--;
AT> flag_want_write=0;
AT> //ставим евент, что могут читать
AT> set_event(event_can_read)

AT> }

AT> ух блин,
AT> пpавда не увеpен что count_threads синхpонизиpованый будет, надо домутить

AT> Hу я вроде все сказал... Пока Dmitry!

... Я буду воевать только за красных!

--- Mutt/1.5.18 (2008-05-17)
* Origin: Debian GNU Linux (2:5020/830.100)

Ответы на это письмо:

From: Username
Заголовок следующего сообщения в треде может быть длинным и его придется перенести на новую строку

From: Username
Или коротким

FGHI-url этого письма: area://RU.CPP?msgid=2:5020/830.100+46a6868f