Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];

Вниз

разделение общего ресурса на несколько потоков   Найти похожие ветки 

 
supervk ©   (2006-08-31 05:17) [0]

Есть приложение, в котором работает несколько потоков. И есть общий ресурс, к которому не должен осуществляться одновременный доступ нескольких потоков, а только поочерёдно.

Правильно ли будет разделит его таким образом:

while( !fl_stop )
begin
    WaitForSingleObject(ResourceFree, INFINITE);
    ResetEvent(ResourceFree);
    [... код использующий общие ресурсы ...]
    SetEvent(ResourceFree);
end;
где ResourceFree - общий handle.

Возникает мысль, что все потоки одновременно выйдут из WaitForSingleObject. Если это так, то каким образом лучше сделать такое разделение общего ресурса?


 
atruhin ©   (2006-08-31 06:45) [1]

> Возникает мысль, что все потоки одновременно выйдут из WaitForSingleObject

Не бойся не выйдут.

> то каким образом лучше сделать такое разделение общего ресурса

Почитай Рихтера, все зависит от задачи: критические секции, Event, Semaphore, для всего есть применение.


 
supervk ©   (2006-08-31 07:11) [2]


>atruhin
> Не бойся не выйдут.

Для пущей уверенности убрал сброс ResetEvent и установил флаг bManualReset=False в CreateEvent, создающем handle ResourceFree.


>atruhin
> Почитай Рихтера, все зависит от задачи: критические секции,
>  Event, Semaphore, для всего есть применение.

Ясно. Спасибо.


 
medved_68 ©   (2006-08-31 08:55) [3]


> Для пущей уверенности убрал сброс ResetEvent и установил
> флаг bManualReset=False в CreateEvent, создающем handle
> ResourceFree.

Ну тогда точно выйдут!!!! А флаг то в автомат нафига перевел????


 
medved_68 ©   (2006-08-31 08:57) [4]

А для поочередности существует такая весчь как критическая секция


 
Сергей М. ©   (2006-08-31 09:18) [5]


> medved_68 ©   (31.08.06 08:57) [4]
> для поочередности существует такая весчь как критическая
> секция


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


 
medved_68 ©   (2006-08-31 09:25) [6]

Сергей М.
> но в ряде случаев м.б. неприменимо из-за блокирования нити


> begin
>     WaitForSingleObject(ResourceFree, INFINITE);

А это не блокирование нити???? И возможно, опять же по ряду причин, "навечно" :)


 
supervk ©   (2006-08-31 09:27) [7]


> medved_68 ©
> > Для пущей уверенности убрал сброс ResetEvent и установил
> > флаг bManualReset=False в CreateEvent, создающем handle
> > ResourceFree.
> Ну тогда точно выйдут!!!! А флаг то в автомат нафига перевел?

В MSDN написано по поводу bManualReset :
Boolean that specifies whether a manual-reset or auto-reset event object is created. If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled. If FALSE, the system automatically resets the state to nonsignaled after a single waiting thread has been released.

Я это понял так: событие автоматически сбросится после того, как на него сработает первый же ждущий его поток.
Т.е. первый WaitForSingleObject, ожидающий его, после срабатывания снова сбросит (отключит) этот event.

Я неправильно понял?


 
Сергей М. ©   (2006-08-31 09:28) [8]


> А это не блокирование нити


Да, разумеется.
Но, во-первых, никто не завставляет использовать именно INFINITE, а во-вторых на то есть есть MsgWaitForMultipleObjects()


 
Сергей М. ©   (2006-08-31 09:30) [9]


> supervk ©   (31.08.06 09:27) [7]


Не следует использовать ивенты для межпоточной синхронизации, для этой цели есть мьютексы и семафоры, если крит.секции по каким-то причинам не устраивают.


 
medved_68 ©   (2006-08-31 09:31) [10]


> Я это понял так: событие автоматически сбросится после того,
>  как на него сработает первый же ждущий его поток.
> Т.е. первый WaitForSingleObject, ожидающий его, после срабатывания
> снова сбросит (отключит) этот event.
>
> Я неправильно понял?

Да неправильно. Событие автоматически сбросится при первой команде WaitForSingleObject


 
medved_68 ©   (2006-08-31 09:34) [11]

Т.е. WaitForSingleObject сбросит событие и уложит поток в анабиоз до наступления события, которое может и не наступить :)))


 
Сергей М. ©   (2006-08-31 09:39) [12]


> medved_68 ©   (31.08.06 09:34) [11]


Вот мьютексы тут и предпочтительней, хотя бы даже по этой причине.
Для случая с мьютексами "анабиоз" не так страшен, поскольку есть WAIT_ABANDONED.


 
medved_68 ©   (2006-08-31 09:47) [13]


> а во-вторых на то есть есть MsgWaitForMultipleObjects()

Сергей М А у него в треде есть выборка сообщений??? И вообще он что нибудь посылает треду??? Вероятность что тред не "проснется" раньше чем надо???Или позже??? Что то много сразу вопросов возникло, как то абстрактно все это!!!
supervk А код можно привести??? А то на кофе гадать, что лучше.... :)))

> Не следует использовать ивенты для межпоточной синхронизации

Сергей М Ну а зачем тогда они нужны, если не для этого??? Мы ведь говорим о тредах одного приложения, или нет???


 
medved_68 ©   (2006-08-31 09:57) [14]


> Вот мьютексы тут и предпочтительней

Наверное....Без кода спорить.....Ну в любом случае автору виднее, а его логику постигать.....Да и нужно ли нам это???
> Если это так, то каким образом лучше сделать такое разделение
> общего ресурса?

Если следовать его логике (пост1), то все же критическая секция :))


 
Сергей М. ©   (2006-08-31 10:03) [15]


> medved_68 ©   (31.08.06 09:47) [13]


> у него в треде есть выборка сообщений?


Без кода сказать, конечно, сложно.
Просто есть подозрение, что одна из синхронизируемых нитей - основная.


> зачем тогда они нужны, если не для этого?


Ивенты скорее предназначены для использования в кач-ве "стартового пистолета" - ивент просигналил, и все нити, которые ждали этого сигнала, мгновенно "сорвались с места".


 
Сергей М. ©   (2006-08-31 10:10) [16]

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


 
supervk ©   (2006-08-31 10:43) [17]

Большое спасибо, очень помогли. Почитал про критические секции, вроде бы то что мне надо. Не использовал их потому что не знал об их существовании.

Что касается программы и кода - речь идёт об использовании несколькими потоками одного - общего сокета для отправки результатов работы потока. Код полностью приводить не стал по причинам:
1) Мудрёности полного кода. Вроде бы как незачем засорять чужие мозги, а  краткую суть проблемного участка я попытался изложить в первом посте.
2) Написан на c++

Т.е. в моём случае в потоки будут использовать код следующим образом:
EnterCriticalSection( Section );
SendTo(soc, buf, len, 0, addr_to, to_len);
LeaveCriticalSection( Section );


 
Сергей М. ©   (2006-08-31 10:49) [18]


> supervk ©   (31.08.06 10:43) [17]


Хотя исключ.ситуации при вызовах API-функций и маловероятны, все же следует их предусматривать

EnterCriticalSection(..);
try
 SendTo(..);
finally
 LeaveCriticalSection(..);
end;


 
supervk ©   (2006-08-31 11:04) [19]

Что касается кода. Если кому надо/интересно, смысл следующий:

Основной поток создаёт TCP сокет и при подключении клиента выносит его обработку в отдельный поток:

clnt_sock = accept(recv_sock, (struct sockaddr *)&client, &addr_sz);          
CreateThread(NULL, 0, thrd_process_client, this, 0, &thread_id);


Потоки обрабатывают информацию получаемую от клиентов, а результаты обработки сливают через общий сокет:

recv_size = recv(clnt_sock, (char *)buf, buf_sz, 0);
process(buf, buf_sz, send_buf, &makd_size);
::EnterCriticalSection( &locker );
sendto(send_sock, (char *)send_buf, makd_size, 0, (SOCKADDR *)&taddr_addr[i], sizeof(taddr_addr[i]));
::LeaveCriticalSection( &locker );


 
Сергей М. ©   (2006-08-31 13:32) [20]


> supervk ©   (31.08.06 11:04) [19]


Для серьезных серверов, способных максимально быстро реагировать на запросы клиентов, такая схема, мягко говоря, не желательна.

Создание и старт нового кодового потока - операция не мгновенная и "тяжелая" для ОС, ее можно сравнить со стартом холодного автодвигателя в морозное время.

В этом плане крайне желательна организация пула и пул-менеджера потоков.


 
supervk ©   (2006-08-31 13:45) [21]


> Сергей М. ©   (31.08.06 13:32) [20]
> Для серьезных серверов, способных максимально быстро реагировать
> на запросы клиентов, такая схема, мягко говоря, не желательна.

Максимум, что будет - 10 потоков. Причем постоянных, отключаться и подключаться они будут редко и то в результате сбоя в сети. Один из главных критериев на данный момент - скорость разработки, а она определяется моими знаниями.
Про пулы менеджеров мне пока ничего не известно. Но буду иметь ввиду.


 
supervk ©   (2006-08-31 13:46) [22]


> Сергей М. ©   (31.08.06 13:32) [20]
> Для серьезных серверов, способных максимально быстро реагировать
> на запросы клиентов, такая схема, мягко говоря, не желательна.

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


 
medved_68 ©   (2006-08-31 13:57) [23]

supervk
> Потоки обрабатывают информацию получаемую от клиентов, а
> результаты обработки сливают через общий сокет:

А кому сливают??? Главному треду приложения или вообще на другую машину???


 
supervk ©   (2006-08-31 14:00) [24]


> medved_68   (31.08.06 13:57) [23]
> А кому сливают??? Главному треду приложения или вообще на
> другую машину???

На другие машины в сети. Через датаграммы UDP.


 
Сергей М. ©   (2006-08-31 14:18) [25]


> supervk ©   (31.08.06 14:00) [24]


> Через датаграммы UDP


Надеюсь, ты осознаешь, что UDP есть протокол без гарантии доставки ?


 
supervk ©   (2006-08-31 14:34) [26]


> Надеюсь, ты осознаешь, что UDP есть протокол без гарантии
> доставки ?

Осознаю. ТЗ такое. Клиенты, которым переправляются пакеты, только UDP и понимают.


 
Сергей М. ©   (2006-08-31 15:29) [27]


> supervk ©   (31.08.06 14:34) [26]


Тем не менее в случае с WSAPI не забывай про try..finally..except



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.012 c
2-1166887149
BanserAnt
2006-12-23 18:19
2007.01.14
Кто находится в чате?


15-1167024646
Gulnaz
2006-12-25 08:30
2007.01.14
Где можно найти учет пользователя Interbase?


15-1166717314
kaZaNoVa
2006-12-21 19:08
2007.01.14
Чем лучше всего распознать фотки документов?


2-1166981875
sinus
2006-12-24 20:37
2007.01.14
Вписать форму в другую форму


1-1164358778
bva
2006-11-24 11:59
2007.01.14
Длинная строка в ComboBox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский