Friday, May 6, 2011

C++ thread: A strange problem sending stdout to the GUI

Today I implemented a new thread for analysis, so the main thread can continue to listen for input from GUI during the analysis, when the "stop" command is sent, I just have to update a flag m_StopAnalysis to true and the thread exit with the serach results, this is very helpful and easy to implement. Concretely, when the GUI send the "go" command, I just call LaunchThreadAnalysis(), defined like this in my code :

void CProtocolUci::LaunchThreadAnalysis()
{
   CProtocolUci *p = this;
   HANDLE hProcessThread = CreateThread(NULL, 0,&CProtocolUci::ThreadLauncher, p,0,NULL);
   if ( hProcessThread == NULL ){
     MessageBoxA(NULL,"Thread error : "+GetLastError(),"Critical error",MB_OK | MB_ICONINFORMATION);
     exit(0);
   }
}


The pointer of the current class is sent as parameter to the function ThreadLauncher, Defined with the followed code :

static DWORD WINAPI ThreadLauncher(void *p)
{
   CProtocolUci *GameAnalysis = reinterpret_cast(p);
   GameAnalysis->LaunchingAnalysis();
   return (0);
}

Finally the function LaunchingAnalysis(), part of the same class is called, and it launch the Analysis. This call Alpha-Beta and write "info" and "bestmove" informations to the stdout in order to reply to the GUI, and then exit from the thread.
I tested with command line : it works perfectly. But when I tested with Arena, the Engine never replied until the GUI send "stop"... Very strange, in depth 4, the engine should find the result in less of 2 seconds, but it never reply, even after 1 minute. After 2 hours of investigation, I found the problem : the behavior of the stdout from the child process is different, it seems to bufferize the characters sent to the GUI...
If you have same problem, the solution is simple : after each stdout, use fflush(stdout); ! This should flush the stdout pipe and send your characters to the GUI.

No comments:

Post a Comment