Click to See Complete Forum and Search --> : winsock: function select() work in wrong way under release version.


homeryan
March 20th, 2008, 09:10 PM
I'm writing a server program, My ide is vs2005. When the program is built in "debug version", it works all right, but when the program is built in "release version", it works in wrong way.
The part of source code follows:

while(WaitForSingleObject(hEventWork, 0) == WAIT_TIMEOUT)
{
Sleep(10);
FD_ZERO(&fdset_accept);
FD_SET(svr_sock, &fdset_accept);
// the follow select can't work in release version, it will return 0 even though there are some income connections pending
if (select(0, &fdset_accept, NULL, NULL, &waittime) > 0)
{
if ((sk_income =accept(svr_sock, &arrive_sock_addr, &addrlen)) == INVALID_SOCKET)
{
break;
}
if (g_tHandleCount < MAX_THREAD_LIMIT)
{
HANDLE hNewThread = CreateThread(NULL, 0, ThreadTransfor, (LPVOID)sk_income, CREATE_SUSPENDED, NULL);
if (hNewThread != NULL)
{
g_tHandle[g_tHandleCount++] = hNewThread;
ResumeThread(hNewThread);
}
else
{
dwret = GetLastError();
}
}
else
{
closesocket(sk_income); // Too many threads
}
}
// test for child threads ending
if (g_tHandleCount > 0)
{
dwWaitResult = WaitForMultipleObjects(g_tHandleCount, g_tHandle, FALSE, 0);
switch(dwWaitResult)
{
case WAIT_FAILED:
break;
case WAIT_TIMEOUT:
break;
default:
if (dwWaitResult >= WAIT_OBJECT_0 && dwWaitResult <= WAIT_OBJECT_0 + g_tHandleCount -1)
{
CloseHandle(g_tHandle[dwWaitResult]);
for(int i = dwWaitResult; i < MAX_THREAD_LIMIT; i++)
{
g_tHandle[i] = g_tHandle[i+1];
}
g_tHandleCount--;
}
break;
}
}
}

Richard.J
March 21st, 2008, 04:51 AM
how do you initialize waittime?
If select returns 0, then a timeout happened. In debug mode, all variables are initialized (to 0xcdcd, I believe) and in release mode, they are not. Maybe waittime is 0 and thus select() returns immediately.

MikeAThon
March 21st, 2008, 11:03 AM
What's the point of calling WaitForSingleObject() with a timeout of zero? Same question for your use of WaitForMultipleObjects(). Both are equivalent to no wait at all, and are thus equivalent to polling for activity which is evil because it is a 100% CPU hog.

homeryan
March 22nd, 2008, 09:49 AM
Thanks Mr.Richard.J and MikeAThon
To Richard:
I have mananualy set TimeVal to {0,0} in the code because I just want to test the status for the svr_sock, thus this thread wouldn't hung for some seconds.
To MikeAThon:
The reason of calling WaitForSingleObject() and WaitForMultiObjects() with a timeout of 0 is just like above, I just don't want the thread hunging while some incoming connections maybe pending. I know this is a "stupid way" because I do notice the CPU payload is 100%, my solution is inserting a Sleep(10) in code as you see, do you know any other way to improve the performance?

MikeAThon
March 22nd, 2008, 10:00 AM
...To MikeAThon:
The reason of calling WaitForSingleObject() and WaitForMultiObjects() with a timeout of 0 is just like above, I just don't want the thread hunging while some incoming connections maybe pending. I know this is a "stupid way" because I do notice the CPU payload is 100%, my solution is inserting a Sleep(10) in code as you see, do you know any other way to improve the performance?
Yes. Use an asynchronous architecture for socket notifications. There are several in the winsock API: WSAAsyncSelect (which uses Windows messaging for notifications of socket activity), WSAEventSelect (which uses event-based notifications), and IOCP (which uses I/O completion ports). Pick your architecture based on the projected number of simultaneous connections to your server. For a small number of simultaneous connections (less than 200 or so) us WSAAsyncSelect since then you can do everything in one thread (i.e., both UI programming and socket programming). For a very large number of simultaneous connections (greater than 1000-2000), use IOCP. In between, use WSAEventSelect.

Note that these are all OS-specific, i.e., they are supported only under Windows. If your code must be portable across OSs, then you must stick with a select-based architecture.

Mike

homeryan
March 23rd, 2008, 10:07 AM
The question is clear, Windows Fireware blocks the release version, and the debug version has been add to the exception list while I was unware that, so...

Thank you mike for the introduce of socket programming model for me, thanks again.

Grober
March 26th, 2008, 11:00 AM
Pick your architecture based on the projected number of simultaneous connections to your server.

No. Always use overlapped i/o with IOCP. There is no reason to use WSAAsyncSelect/WSAEventSelect.