In my day job , I solved a communication problem using a different method which I now use in my chess engine. I would like to share it here. I'll present my chess engine solution to keep things in context.
Basically, the idea is to use a second thread for the search portion of the engine and use the main program thread for the communications. It is very simple to set up. My engine only uses a single thread for searching, but i'm sure a multi-threaded search solution would still work in this model.
After doing some initialization the following few lines of code are called from the main() function.
Code: Select all
// start the search thread
HANDLE hSearch;
hSearch = (HANDLE)_beginthread(SearchThread, 0, NULL);
CommLoop();
return 0;
Code: Select all
void SearchThread(void *)
{
// this method is started by a thread
// it stays in this loop until the program exits
for (;;)
{
if (cs.Exit)
break;
if (cs.task == TASK_NOTHING) { Sleep(100); }
else {
SearchRun();
cs.task = TASK_NOTHING;
}
}
_endthread();
}
The CommLoop() handles the data from the input stream and the implementation isn't important to this exercise, but I will say that the code spends most of its time waiting for input and then only reacts once a command is received.
Inside the search code, there still is a call to determine if the search should terminate, but there is no need to check for input.
To exit the program, the communication code sets cs.Exit to true when a "quit" command is received from the UCI overlord or, also from my own console interface (used for testing). The search thread then destroys itself via the _endthread() call. At the same time, the CommLoop() code exits and the main() program exits.
I hope this is useful.