Форум: "Сети";
Текущий архив: 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