|
-
September 29th, 2010, 08:30 AM
#1
Sleep(0)
Hello,
I have the following scenario:
Multi-Threaded Server Application.
I have a function which PeekMessage() all messages and returns if none left.
I have a function that must be called every 12,5 ms.
pseudo code:
Code:
bool PumpWindowMessages()
{
MSG msg;
while( PeekMessage( &msg ) )
{
if( msg.message == WM_QUIT )
return false;
TranslateMessage( &msg );
Dispatchmessage( &msg );
}
return true;
}
void TheInfiniteLoop()
{
LARGE_INTEGER liFreq, liStart, liStop;
float fTime = 0.0f
QueryPerformanceFrequency( &liFreq );
while( PumpWindowMessages() )
{
QueryPerformanceCounter( &liStart );
Update( fTime );
QueryPerformanceCounter( &liStop );
fTime += (float)(((liStop - liStart) * 1000000) / liFreq);
Sleep( 0 );
}
}
void Update( float fTime )
{
static float fTickTime = 0.0f;
fTickTime += fTime;
while( fTickTime >= 12.5f )
{
doMyFunctions()
fTickTime -= 12.5f;
}
}
void doMyFunctions()
{
EnterCriticalSection( &mainCritSec );
CheckEverything();
LeaveCriticalSection( &mainCritSec );
}
What do you think of this? Could it be done better? Since CPU load could be high due to the infinite loop, though the Sleep( 0 ) should reduce this.
Some extra notes:
Every incoming packet is received on another thread, but then with SendMessage() sent to the WndProc (WM_PACKET), so packets are handled in the main thread of the application.
Last edited by ProgrammerC++; September 29th, 2010 at 08:40 AM.
-
October 1st, 2010, 04:33 AM
#2
Re: Sleep(0)
As soon as you do Sleep() all bets are off on making that 12.5ms mark. Sleep(0) doesn't guarantee you'll return after zero time has elapsed. It merely guarantees that it will return "as soon as windows will allow, at least 0ms after the sleep call". But that could mean several hundred ms. Even without the sleep, the windows scheduler may decide not to give your thread any time for several hundred ms.
If that 12.5ms is really crucial. I'd suggest looking at a multimediatimer.
-
October 1st, 2010, 10:44 PM
#3
Re: Sleep(0)
 Originally Posted by ProgrammerC++
Some extra notes:
Every incoming packet is received on another thread, but then with SendMessage() sent to the WndProc (WM_PACKET), so packets are handled in the main thread of the application.
If receiving data is critical, then keep the main UI thread out of it. The reason being is because SendMessage is synchronous, and since you can't control what the user is doing, [excessive] UI activity could very well cause your data retrieval thread to be hung up resulting in lost data.
-
October 2nd, 2010, 06:53 AM
#4
Re: Sleep(0)
I've already realized that this approach is consuming 100% cpu.
Instead I'm using an endless GetMessage() loop in the main thread and have a seperate thread Send a User defined message 'WM_UPDATE' to do the time based actions that have to be done in the main thread.
My message loop WndProc actually only handles all client interactions, WM_SOCKETACCEPT to handle a socket accept, WM_SOCKETPACKET to handle a packet, WM_SOCKETCLOSE to close a socket. This is all synchornized so Critical Sections are not necessary. A server basicly only has to handle Client Interactions and Time Based events, so there's not more to it.
The server application is not fully built to be multithreaded, There are just a few other threads but none that are time critical, except for sending and receiving data:
I have a 2 thread per client system (with small stacks), one for sending and one for receiving. This approach works fine for now.
-
October 2nd, 2010, 01:34 PM
#5
Re: Sleep(0)
 Originally Posted by ProgrammerC++
My message loop WndProc actually only handles all client interactions, WM_SOCKETACCEPT to handle a socket accept, WM_SOCKETPACKET to handle a packet, WM_SOCKETCLOSE to close a socket. This is all synchornized so Critical Sections are not necessary. A server basicly only has to handle Client Interactions and Time Based events, so there's not more to it.
This is a poor design. As mentioned before, if the UI thread is 'handling' the data packet, then operations of the user can interfere with the processing and packets can be missed.
Furthermore, synchronizing operations between a worker thread and UI thread by using SendMessage (besides the issues above) often negates the parallel benefits that a thread brings to the table.
As far as not using a critical section, it seems that lately some folks have some sort of bias against using a cs, when in fact, using the cs is really the most straightforward way of handling this class of problem and rarely results in the performance penalty it's thought to cause.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|