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

Вниз

WinSock2 API: количество дескрипторов.   Найти похожие ветки 

 
panov   (2003-07-02 16:02) [0]

При работе c WSASelectEvent, WSAResetEvent для обработки входящих запросов на подключение(перед Accept) возникает следующая ситуация:

После выполнения WSAEventSelect(S3Sock^.fSocket,S3Sock^.fEvent,FD_ACCEPT); количество дескрипторов, используемых программой(Видно в Task Manager) увеличивается на 2.
После выполнения WSAResetEvent(S3Sock^.fEvent); количество дескрипторов остается прежним.

Используется таким образом:

...
...
PS3SocketS = ^TS3SocketS;
TS3SocketS = packed record
fSocket: DWORD;
fSA: TSockAddr;
Status: TS3StatusSocket;
fEvent: THandle;
...
...
fTimeOut: TTimeVal;
fListClients: TList;
end;

...
...

procedure S3Accept(pParam: Pointer);stdcall;
var
sz: Integer;
Err: Integer;
PSA: ^SOckAddr;
S3Sock: PS3SocketS;
tId: THandle;
hThread: THandle;
begin
S3Sock := pParam;
WSAResetEvent(S3Sock^.fEvent);
WSAEventSelect(S3Sock^.fSocket,S3Sock^.fEvent,FD_ACCEPT);
WaitForSingleObject(S3Sock^.fEvent,INFINITE);
New(PSA);
sz := SizeOf(PSA^);
Err := Accept(S3Sock^.fSocket,PSA^,sz);
hThread := CreateThread(nil,0,@S3Accept,S3Sock,0,tId);
if hThread=0 then ...

if Err = INVALID_SOCKET then
begin
Dispose(PSA);
Err := WSAGetLastError;
...
...
( Err,SD_SEND)
При работе c WSASelectEvent, WSAResetEvent для обработки входящих запросов на подключение(перед Accept) возникает следующая ситуация:

После выполнения WSAEventSelect(S3Sock^.fSocket,S3Sock^.fEvent,FD_ACCEPT); количество дескрипторов, используемых программой(Видно в Task Manager) увеличивается на 2.
После выполнения WSAResetEvent(S3Sock^.fEvent); количество дескрипторов остается прежним.

Используется таким образом:

...
...
PS3SocketS = ^TS3SocketS;
TS3SocketS = packed record
fSocket: DWORD;
fSA: TSockAddr;
Status: TS3StatusSocket;
fEvent: THandle;
...
...
fTimeOut: TTimeVal;
fListClients: TList;
end;

...
...

procedure S3Accept(pParam: Pointer);stdcall;
var
sz: Integer;
Err: Integer;
PSA: ^SOckAddr;
S3Sock: PS3SocketS;
tId: THandle;
hThread: THandle;
begin
S3Sock := pParam;
WSAResetEvent(S3Sock^.fEvent);
WSAEventSelect(S3Sock^.fSocket,S3Sock^.fEvent,FD_ACCEPT);
WaitForSingleObject(S3Sock^.fEvent,INFINITE);
New(PSA);
sz := SizeOf(PSA^);
Err := Accept(S3Sock^.fSocket,PSA^,sz);
hThread := CreateThread(nil,0,@S3Accept,S3Sock,0,tId);
if hThread=0 then ...

if Err = INVALID_SOCKET then
begin
Dispose(PSA);
Err := WSAGetLastError;
...
...
Exit;
end;

// здесь обработка соединения, затем
Shutdown(Err,SD_SEND);
CloseSocket(Err);
Dispose(PSA);
end;


Таким образом после каждого подключения количество дескрипторов увеличивается.
Память при этом не теряется.

Как бороться с такой ситуацией?
Как много дескрипторов может быть использовано программой?


 
Polevi   (2003-07-02 17:24) [1]

Closing a socket with closesocket also cancels the association and selection of network events specified in WSAEventSelect for the socket. The application, however, still must call WSACloseEvent to explicitly close the event object and free any resources.


 
Digitman   (2003-07-02 17:25) [2]

WSASelectEvent(..., hEvent, ...) - это "открывающая скобка", внешняя. Ей соответствует closehandle(hEvent) как внешняя "закрывающая скобка".

внутии этих скобок ты должен ждать сигнала hEvent любым способом, например, тем же WaitForSingleObject(). Это будет соответствовать "внутренней открывающей скобке"

дождавшись сигнала, либо тут же явно закрой "внутреннюю скобку" вызовом WSAResetEvent() либо вызывай WSAEnumNetworkEvents(), которая сделает то же самое автоматом.

И тогда все будет ОК.


 
panov   (2003-07-02 17:46) [3]

WSASelectEvent(..., hEvent, ...) - это "открывающая скобка", внешняя. Ей соответствует closehandle(hEvent) как внешняя "закрывающая скобка".

см. в топике:
После выполнения WSAEventSelect(S3Sock^.fSocket,S3Sock^.fEvent,FD_ACCEPT); количество дескрипторов, используемых программой(Видно в Task Manager) увеличивается на 2(два).

Т.е. количество дескрипторов после этого +2.

Но после выполнения любой из операций
CloseHandle(), WSACloseEvent счетчик дескрипторов уменьшается на 1(один). (-1)

Т.е. при выполнении таких парных операций программа в каждом цикле теряет 1 дескриптор, что не есть хорошо.

Если нужна доп. информация(код), то могу выложить сюда, его не так много.


 
panov   (2003-07-02 19:01) [4]

Ошибку нашел. Всем спасибо.

Действительность оказалась менее неприятной, чем казалось.

При создании потока функция CreateThread возвращает дескриптор созданного потока.

Несмотря на то, что в параметрах указано dwCreationFlags=0,
после завершения поточной функции счетчик использования дескриптора потока не уменьшается.

После CloseHandle(hThread) все пришло в норму.



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

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

Наверх




Память: 0.46 MB
Время: 0.009 c
14-24687
Knight
2003-08-19 21:25
2003.09.08
Welcome!!!


7-24718
-=Vlad=-
2003-06-20 12:08
2003.09.08
Распознавание поднятия трубки


3-24361
Bes
2003-08-17 05:18
2003.09.08
Паралельная работа с БД...


3-24344
Alex9
2003-08-18 07:57
2003.09.08
Запись данных на диск


3-24340
Зозуля Юрий
2003-08-18 10:32
2003.09.08
Как привести тип dbitblname





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский