![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
разделение общего ресурса на несколько потоков
supervk © (2006-08-31 05:17:00)Есть приложение, в котором работает несколько потоков. И есть общий ресурс, к которому не должен осуществляться одновременный доступ нескольких потоков, а только поочерёдно.
Правильно ли будет разделит его таким образом:
while( !fl_stop )
begin
WaitForSingleObject(ResourceFree, INFINITE);
ResetEvent(ResourceFree);
[... код использующий общие ресурсы ...]
SetEvent(ResourceFree);
end;
где ResourceFree - общий handle.
Возникает мысль, что все потоки одновременно выйдут из WaitForSingleObject. Если это так, то каким образом лучше сделать такое разделение общего ресурса?
Сергей М. (2006-08-31 15:29:00) [1]
> supervk © (31.08.06 14:34) [26]
Тем не менее в случае с WSAPI не забывай про try..finally..except
supervk (2006-08-31 14:34:00) [2]
> Надеюсь, ты осознаешь, что UDP есть протокол без гарантии
> доставки ?
Осознаю. ТЗ такое. Клиенты, которым переправляются пакеты, только UDP и понимают.
Сергей М. (2006-08-31 14:18:00) [3]
> supervk © (31.08.06 14:00) [24]
> Через датаграммы UDP
Надеюсь, ты осознаешь, что UDP есть протокол без гарантии доставки ?
supervk (2006-08-31 14:00:00) [4]
> medved_68 (31.08.06 13:57) [23]
> А кому сливают??? Главному треду приложения или вообще на
> другую машину???
На другие машины в сети. Через датаграммы UDP.
medved_68 (2006-08-31 13:57:00) [5]supervk
> Потоки обрабатывают информацию получаемую от клиентов, а
> результаты обработки сливают через общий сокет:
А кому сливают??? Главному треду приложения или вообще на другую машину???
supervk (2006-08-31 13:46:00) [6]
> Сергей М. © (31.08.06 13:32) [20]
> Для серьезных серверов, способных максимально быстро реагировать
> на запросы клиентов, такая схема, мягко говоря, не желательна.
Максимум, что будет - 10 потоков. Причем постоянных, отключаться и подключаться они будут редко и то в результате сбоя в сети. Один из главных критериев на данный момент - скорость разработки, а она определяется моими знаниями.
Мне же пока про пулы менеджеров ничего не известно. Но буду иметь ввиду на будущее.
supervk (2006-08-31 13:45:00) [7]
> Сергей М. © (31.08.06 13:32) [20]
> Для серьезных серверов, способных максимально быстро реагировать
> на запросы клиентов, такая схема, мягко говоря, не желательна.
Максимум, что будет - 10 потоков. Причем постоянных, отключаться и подключаться они будут редко и то в результате сбоя в сети. Один из главных критериев на данный момент - скорость разработки, а она определяется моими знаниями.
Про пулы менеджеров мне пока ничего не известно. Но буду иметь ввиду.
Сергей М. (2006-08-31 13:32:00) [8]
> supervk © (31.08.06 11:04) [19]
Для серьезных серверов, способных максимально быстро реагировать на запросы клиентов, такая схема, мягко говоря, не желательна.
Создание и старт нового кодового потока - операция не мгновенная и "тяжелая" для ОС, ее можно сравнить со стартом холодного автодвигателя в морозное время.
В этом плане крайне желательна организация пула и пул-менеджера потоков.
supervk (2006-08-31 11:04:00) [9]Что касается кода. Если кому надо/интересно, смысл следующий:
Основной поток создаёт 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 10:49:00) [10]
> supervk © (31.08.06 10:43) [17]
Хотя исключ.ситуации при вызовах API-функций и маловероятны, все же следует их предусматривать
EnterCriticalSection(..);
try
SendTo(..);
finally
LeaveCriticalSection(..);
end;
supervk (2006-08-31 10:43:00) [11]Большое спасибо, очень помогли. Почитал про критические секции, вроде бы то что мне надо. Не использовал их потому что не знал об их существовании.
Что касается программы и кода - речь идёт об использовании несколькими потоками одного - общего сокета для отправки результатов работы потока. Код полностью приводить не стал по причинам:
1) Мудрёности полного кода. Вроде бы как незачем засорять чужие мозги, а краткую суть проблемного участка я попытался изложить в первом посте.
2) Написан на c++
Т.е. в моём случае в потоки будут использовать код следующим образом:
EnterCriticalSection( Section );
SendTo(soc, buf, len, 0, addr_to, to_len);
LeaveCriticalSection( Section );
Сергей М. (2006-08-31 10:10:00) [12]Есть, правда, еще один механизм, позволяющий в т.ч. синхронизировать обращение к ресурсам - волокна (файберы), но механизм этот доступен только в НТ-линейке, да и использование его довольно сложно в прикладной реализации (ощутимо сложней, нежели использование механизма нитей), хотя дает ощутимый выигрыш в сквозной производительности приложения.
Сергей М. (2006-08-31 10:03:00) [13]
> medved_68 © (31.08.06 09:47) [13]
> у него в треде есть выборка сообщений?
Без кода сказать, конечно, сложно.
Просто есть подозрение, что одна из синхронизируемых нитей - основная.
> зачем тогда они нужны, если не для этого?
Ивенты скорее предназначены для использования в кач-ве "стартового пистолета" - ивент просигналил, и всенити, которые ждали этого сигнала, мгновенно "сорвались с места".
medved_68 (2006-08-31 09:57:00) [14]
> Вот мьютексы тут и предпочтительней
Наверное....Без кода спорить.....Ну в любом случае автору виднее, а его логику постигать.....Да и нужно ли нам это???
> Если это так, то каким образом лучше сделать такое разделение
> общего ресурса?
Если следовать его логике (пост1), то все же критическая секция :))
medved_68 (2006-08-31 09:47:00) [15]
> а во-вторых на то есть есть MsgWaitForMultipleObjects()
Сергей МА у него в треде есть выборка сообщений??? И вообще он что нибудь посылает треду??? Вероятность что тред не "проснется" раньше чем надо???Или позже??? Что то много сразу вопросов возникло, как то абстрактно все это!!!
supervkА код можно привести??? А то на кофе гадать, что лучше.... :)))
> Не следует использовать ивенты для межпоточной синхронизации
Сергей МНу а зачем тогда они нужны, если не для этого??? Мы ведь говорим о тредах одного приложения, или нет???
Сергей М. (2006-08-31 09:39:00) [16]
> medved_68 © (31.08.06 09:34) [11]
Вот мьютексы тут и предпочтительней, хотя бы даже по этой причине.
Для случая с мьютексами "анабиоз" не так страшен, поскольку есть WAIT_ABANDONED.
medved_68 (2006-08-31 09:34:00) [17]Т.е. WaitForSingleObject сбросит событие и уложит поток в анабиоз до наступления события, которое может и не наступить :)))
medved_68 (2006-08-31 09:31:00) [18]
> Я это понял так: событие автоматически сбросится после того,
> как на него сработает первый же ждущий его поток.
> Т.е. первый WaitForSingleObject, ожидающий его, после срабатывания
> снова сбросит (отключит) этот event.
>
> Я неправильно понял?
Да неправильно. Событие автоматически сбросится при первой командеWaitForSingleObject
Сергей М. (2006-08-31 09:30:00) [19]
> supervk © (31.08.06 09:27) [7]
Не следует использовать ивенты для межпоточной синхронизации, для этой цели есть мьютексы и семафоры, если крит.секции по каким-то причинам не устраивают.
Сергей М. (2006-08-31 09:28:00) [20]
> А это не блокирование нити
Да, разумеется.
Но, во-первых, никто не завставляет использовать именно INFINITE, а во-вторых на то есть есть MsgWaitForMultipleObjects()