Threading in C

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

Threading in C

Postby Jaco van Niekerk » 09 Apr 2007, 15:43

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!
User avatar
Jaco van Niekerk
 
Posts: 31
Joined: 30 Jul 2006, 21:23
Location: South Africa

Re: Threading in C

Postby Dann Corbit » 09 Apr 2007, 21:33

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.
Dann Corbit
 

Re: Threading in C

Postby Alessandro Scotti » 10 Apr 2007, 15:28

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).
User avatar
Alessandro Scotti
 
Posts: 306
Joined: 20 Nov 2004, 00:10
Location: Rome, Italy

Re: Threading in C

Postby Jaco van Niekerk » 11 Apr 2007, 07:19

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.
User avatar
Jaco van Niekerk
 
Posts: 31
Joined: 30 Jul 2006, 21:23
Location: South Africa

Re: Threading in C

Postby Pradu » 11 Apr 2007, 07:40

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.
User avatar
Pradu
 
Posts: 343
Joined: 12 Jan 2005, 19:17
Location: Chandler, Arizona, USA

Re: Threading in C

Postby Alessandro Scotti » 11 Apr 2007, 07:48

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! :-)
User avatar
Alessandro Scotti
 
Posts: 306
Joined: 20 Nov 2004, 00:10
Location: Rome, Italy

Re: Threading in C

Postby Jaco van Niekerk » 11 Apr 2007, 08:25

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:))
User avatar
Jaco van Niekerk
 
Posts: 31
Joined: 30 Jul 2006, 21:23
Location: South Africa


Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 46 guests