Page 1 of 1

Threading in C

PostPosted: 09 Apr 2007, 15:43
by Jaco van Niekerk
Hi all

Although my C knowledge is limited, I have decided to write my chess engine is C. It now has a fairly quick move generation (12x12 board technique), alpha-beta with quiescence search on captures/promotions (using MVV/LVA for ordering). It also keeps track of 3-fold repetition using Zobrist keys with the aid of a dedicated position cache. As you can see I still have a lot to do!

I am now playing around with getting Winboard to work, deciding to use threads for that purpose. I got a basic I/O thread working, but I am struggling to get it to terminate gracefully as the thread is stuck waiting for input when it should be terminating (so actually I cannot get it to terminate at all!). The basic outline is as follows.
Code: Select all
#define BUFFERSIZE 10

CRITICAL_SECTION section;
char buffer[BUFFERSIZE][100];
int terminate;

void reader(void *arg)
{
  char tmp[100];   
  while (!terminate)
  {
    scanf("%s", tmp);
    /* if buffer full, sleep a while and test again ... */
    EnterCriticalSection(&section);   
    /* add to buffer... */
    LeaveCriticalSection(&section);        
  }
}

int readui(char* data)
{
  /* if buffer empty, return 0... */
  EnterCriticalSection(&section);
  /* get next input and copy into data... */
  LeaveCriticalSection(&section);
  return 1;
}

int winboard()
{
  HANDLE hThread;   
  InitializeCriticalSection(&section);   
  hThread=(HANDLE)_beginthread(reader, 0, NULL);
  /* While game has not ended, do game stuff... */
  terminate = 1;
  printf("\nTerminating..."); 
  /*?? and right hereabouts it hangs.... ??*/
  WaitForSingleObject(hThread, INFINITE);
  DeleteCriticalSection(&section);
}

int main()
{
  winboard();     
}


Any ideas or pointers would be greatly appreciated. BTW, I am keeping a blog of my progress on the engine if you're interested.

Thanks for the help!

Re: Threading in C

PostPosted: 09 Apr 2007, 21:33
by Dann Corbit
Jaco van Niekerk wrote:Hi all

Although my C knowledge is limited, I have decided to write my chess engine is C. It now has a fairly quick move generation (12x12 board technique), alpha-beta with quiescence search on captures/promotions (using MVV/LVA for ordering). It also keeps track of 3-fold repetition using Zobrist keys with the aid of a dedicated position cache. As you can see I still have a lot to do!

I am now playing around with getting Winboard to work, deciding to use threads for that purpose. I got a basic I/O thread working, but I am struggling to get it to terminate gracefully as the thread is stuck waiting for input when it should be terminating (so actually I cannot get it to terminate at all!). The basic outline is as follows.
Code: Select all
#define BUFFERSIZE 10

CRITICAL_SECTION section;
char buffer[BUFFERSIZE][100];
int terminate;

void reader(void *arg)
{
  char tmp[100];   
  while (!terminate)
  {
    scanf("%s", tmp);
    /* if buffer full, sleep a while and test again ... */
    EnterCriticalSection(&section);   
    /* add to buffer... */
    LeaveCriticalSection(&section);        
  }
}

int readui(char* data)
{
  /* if buffer empty, return 0... */
  EnterCriticalSection(&section);
  /* get next input and copy into data... */
  LeaveCriticalSection(&section);
  return 1;
}

int winboard()
{
  HANDLE hThread;   
  InitializeCriticalSection(&section);   
  hThread=(HANDLE)_beginthread(reader, 0, NULL);
  /* While game has not ended, do game stuff... */
  terminate = 1;
  printf("\nTerminating..."); 
  /*?? and right hereabouts it hangs.... ??*/
  WaitForSingleObject(hThread, INFINITE);
  DeleteCriticalSection(&section);
}

int main()
{
  winboard();     
}


Any ideas or pointers would be greatly appreciated. BTW, I am keeping a blog of my progress on the engine if you're interested.

Thanks for the help!


The use of scanf() with %s is just as bad as gets() and can lead to exploits. Here is an alternative from Jack Klein's web site:
#include <stdio.h>
#include <string.h>
char *getsafe(char *buffer, int count)
{
char *result = buffer, *np;
if ((buffer == NULL) || (count < 1))
result = NULL;
else if (count == 1)
*result = '\0';
else if ((result = fgets(buffer, count, stdin)) != NULL)
if (np = strchr(buffer, '\n'))
*np = '\0';
return result;
}

If you only have a single reader thread and a single writer thread then you won't have to do all that critical section stuff.

I would recommend using CreateThread instead of _beginthread since that is what is going to happen anyway under the covers but with an additional indirection.

Re: Threading in C

PostPosted: 10 Apr 2007, 15:28
by Alessandro Scotti
Hi Jaco,
it is not really a necessity to use threads for input. Anyway, you can find a free implementation in my chess pages (press WWW button below and look for the "System" library) that will work on Windows and most Unix systems (incl. Linux and Mac OS X). If you are working on the Winboard protocol, there is also a state diagram that can be of some help (it was for me).

Re: Threading in C

PostPosted: 11 Apr 2007, 07:19
by Jaco van Niekerk
I appreciate the suggestions (I've implemented the safer I/O and I now use CreateThread()), but this still does not answer my original question. The thread gets stuck waiting for input when the main program is trying to terminate. What I want to do, is to instruct the thread to die, so that the program can quit. I have tried TerminateThread(hThread, 0); to no avail.

Isn't it possible to specify a timeout for fgets() as it reads from stdin?? (that will solve all my problems!)

Please help.
Thanks.

Re: Threading in C

PostPosted: 11 Apr 2007, 07:40
by Pradu
Jaco van Niekerk wrote:I appreciate the suggestions (I've implemented the safer I/O and I now use CreateThread()), but this still does not answer my original question. The thread gets stuck waiting for input when the main program is trying to terminate. What I want to do, is to instruct the thread to die, so that the program can quit. I have tried TerminateThread(hThread, 0); to no avail.

Isn't it possible to specify a timeout for fgets() as it reads from stdin?? (that will solve all my problems!)

Please help.
Thanks.

Easy solution: whenever you want to terminate your program just call
Code: Select all
#include <stdlib.h>
exit(EXIT_SUCCESS);


Hard solution:
Debug what goes wrong when you call TerminateThread
http://msdn2.microsoft.com/en-us/library/ms686717.aspx
Error Codes after calling GetLastError:
http://msdn2.microsoft.com/en-us/library/ms679360.aspx

I'm pretty sure I saw some input functions with timeout somewhere. Just look around in the WinAPI.

Re: Threading in C

PostPosted: 11 Apr 2007, 07:48
by Alessandro Scotti
Jaco van Niekerk wrote:I appreciate the suggestions (I've implemented the safer I/O and I now use CreateThread()), but this still does not answer my original question. The thread gets stuck waiting for input when the main program is trying to terminate. What I want to do, is to instruct the thread to die, so that the program can quit. I have tried TerminateThread(hThread, 0); to no avail.


Well the code I pointed you at contains the answer but anyway I just close the input handle, which makes ReadFile return an error, which in turn makes the input thread terminate. I wait 500 milliseconds for this to happen, then if it does not I exit anyway and let Windows handle the mess! :-)

Re: Threading in C

PostPosted: 11 Apr 2007, 08:25
by Jaco van Niekerk
Wao, you guys are great! Thanks Alessandro and Pradu! I'm using both your suggestions. Instead of using stdin I now use GetStdHandle(STD_INPUT_HANDLE); When Vicki needs to terminate I simply close the stream, which causes the fgets() to fail immediately. If that does not work for some reason, I simply slaughter the program :)

Now I can get back to the actual chess programming part! Thank you very much.

(BTW. I am a right to say that C (my pet language) does not follow as strict a convention as Java (my money-producing language) does. For example, function names starting with a capital letter, capitalized types, etc. Hope I don't get flamed for this one:))