пытаюсь написать сервер рассчитанный на работу с несколькими клиентами одновременно. с сокетами разобрался. всё как бы ок работает, но! в простое сервер отжирает 99% процессорного времени!! а именно функция accept. Я не могу понять почему. причём это происходит при абсалютно любом приоритете потока в котором вызываеться accept. код потока ниже, который принимает подключения от клиентов. (придумал сам, так что выглядеть может несколько по ламерски). В 98 винде кстате такой ошибки я не замечал... а вот в ХР и 2000 такая фигня твориться. Эти тормоза мешают обработке подключения клиента. А в 98 винде всё работает зишибись. быстро и без глюков. Помогите пожалуйста если не сложно. Что мне сделать, что бы этих тормозов небыло ? Код (Text): unsigned long WINAPI EstablishConnectionProc(void *Param_Socket) { HANDLE DummyEvent = CreateEvent(0, true, false, "EstCon"); SOCKET *ConnectionSocket = (SOCKET*)Param_Socket; SOCKET TempSocket; int SocketError; unsigned int ClientNum = 0; SetThreadPriority(EstablishConnectionThread, THREAD_PRIORITY_NORMAL); /* initialising slots */ for (ClientNum=0; ClientNum<SW_MAX_CLIENTS; ClientNum++) { ClientSocket[ClientNum] = INVALID_SOCKET; } while(true) { SocketError = listen(*ConnectionSocket, 1); if (SocketError == INVALID_SOCKET) { /* problems with connection socket */ MessageBox(NULL, "ServerEstablishThreadFailure", "", MB_OK); //temp closesocket(*ConnectionSocket); ExitThread(SW_THR_SELFKILLED); } /* awaiting connections */ while (true) { /* accept new client if server have free slot */ for (ClientNum=0; ClientNum<SW_MAX_CLIENTS; ClientNum++) { if (ClientSocket[ClientNum] == INVALID_SOCKET) { while (ClientSocket[ClientNum] == INVALID_SOCKET) { ClientSocket[ClientNum] = accept(*ConnectionSocket, NULL, NULL); // вот здесь каждый проход цикла функция отжирает 99% } SvSockReadThread[ClientNum] = CreateThread(NULL, NULL, SvSockReadProc, (void*)&ClientNum, NULL, &SvSockReadThreadID[ClientNum]); if (SvSockReadThread == INVALID_HANDLE_VALUE) { /* cannot create thread for new client */ ClientSocket[ClientNum] = INVALID_SOCKET; WaitForSingleObject(DummyEvent, 1000); break; //returns to awaiting connections } else { WaitForSingleObject(DummyEvent, 1000); //because ClientNum problem break; //returns to awaiting connections } } } WaitForSingleObject(DummyEvent, 1000); //speed optimisation } } }
вообщето такого не замечал . С кодом твоим пока не разбирался (( извини нет времени. Но показать пример обработки соединений могу. На каждый accept создается поток, обрабатывающий соединение. Сделано буквально по минимуму.
а, по поводу твоего кода.. убрал я там 1 строчку - не грузится ничего. (установки приоритета - так как этого треда у меня нет) Может и не из за этой процедуры, которую ты привел, у тебя все грузилось В аттаче пример с твоей функцией. У меня проц не грузится при accept вызове. _1094411211__funct_test2.rar
действительно. это у меня какие-то глюки. мне просто показалось что когда я функцию accept закомментировал, то тормоза прекратились. однако это был еденичный случай. тормозит вообще даже не этот поток. я его переписал (в один while сделал), а затем совсем убрал, но всё равно дикие тормоза. сейчас буду опять искать где. .
всё нашел. почему-от .. по каким-то одному биллу гейтсу причинам тормоза выдавал вот этот вот поток Код (Text): unsigned long WINAPI OutputProc(void *Param) { SetThreadPriority(OutputProcThread, THREAD_PRIORITY_NORMAL); HANDLE DummyEvent = CreateEvent(0, true, false, "SocRea"); while(true) { if (strlen(CommonRecvBuff) != 0) { Form1->Memo2->Lines->Add("ïðèøëî " + IntToStr(strlen(CommonRecvBuff))); EnterCriticalSection(CritSection1); myOutput(CommonRecvBuff); LeaveCriticalSection(CritSection1); } //WaitForSingleObject(DummyEvent, 100); } } Но стоило мне расскоментировать Waitforsingleobject и написать ему ждать 100мс... как тормоза исчезли. я этого не понимаю.. потому что всю жизнь потоки и без WaitForSingleObject пахали отлично и ничего не грузили.. видать это как-то связано с критической секцией. но я не думал, что вход и выход из неё могут ТАК загрузить проц
дык на самом деле ваще ничего не понятно по одной простой причине: CommonRecvBuff у меня заполнен нулевыми байтами. т.е. условие никогда верное не будет. следовательно дело до Memo и до Критической секции не доходит.. не может же strlen в бесконечном цикле занимать 99% процессорного времени 8)).
А вообще очень плохой код.. В цикле постоянно проверять длинну строки. А потом еще раз ее брать.. Мой совет - в этом коде оставить только вывод в мемо и критическую секцию. А вызывать уже этот вывод либо по таймеру, либо установкой евента после удачного завершения функции recv (это будет лучше).
шутишь что ли ?? 8)). это вообще отладочный код. нужен был только для проверки работы сервера. в проге такой ереси естественно не будет.
Народ! Проблемы то нет. Если поток OutputProc в бесконечном цикле чего-то делает, то ему и будет выдаваться очень много процессорного времени (особенности архитектуры мультитрединга). Напиши в этом цикле Sleep(5); и все будет ок. Кусок кода со 100% загрузкой: while(1){ //work } Кусок кода без 100% загрузкой: while(1){ //work Sleep(10); } У самого в сервере была такая же проблема. Написал строчку Sleep(10); и все. В твоем случае вместо Sleep выступает WaitForSingleObject(...,100).