Author: Vincent Diepeveen
Date: 05:04:26 01/04/02
Go up one level in this thread
On January 03, 2002 at 16:02:52, Russell Reagan wrote:
I get the impression you are making things way too difficult
for yourself.
Let's distinguish the differences between threads
a) i/o thread
b) search threads
The synchronization/locking between search threads is an entire
different story of course, as there are very complex ways to do it
to get a parallel speedup. Let's put this under the chapter 'parallellizing
a chessengine'.
We are talking about a versus b here right?
So i/o of your program versus search THREAD (single thread).
to start with i do not see any use for a worker thread, unless my definition
of a worker thread is different: "useless thread doing some background
work now and then".
Either you need an i/o thread (that's not background) that does little
work, or you need a search thread (that's not doing now and then work
but continuesly searching).
The i/o thread you could implement as something that's executing each
say 40 milliseconds and doing a check on i/o then.
i/o thread() {
while( !quitprogram ) {
i = CheckIO();
if( !i ) // after checkio had to do something skip, check directly
// again i/o then to not wait for 40 ms for next input
sleep(40);
}
_endthread();
}
All you need to set then is a volatile variable to stop the search
or whatever. No need to signal objects or whatever. All you need
are a few volatile variables (get always written and read from
memory instead of getting optimized to stay within registers).
volatile int startsearch; // directly after starting a search you put this to 0
volatile int stopsearch;
Sounds way simpler nah?
Nothing as easy than to set them to 0 or 1.
>In my chess program I'm implementing the user input in it's own thread, as well
>as implementing the ability for the main thread to create other worker threads
>to do various tasks (the main one being searching a given position). I'll
>explain my original idea, the problem I encountered with that idea, and my
>solution and see if I missed anything and hopefully get some advice on how to
>handle things correctly.
>
>In each search thread class there is an event object used to determine if the
>thread should shut itself down. So in the Shutdown() method of my thread class I
>have something like this:
>
>MyThreadClass::Shutdown()
>{
> Lock(); // generic lock, implemented by critical section, mutex, whatever
> SetEvent(exitEventHandle);
> Unlock();
>}
>
>I'm doing this because the thread that is to be shut down will have to access
>the exit event hadle, as well as the thread that requests the shutdown. This is
>the first area I'm not entirely sure of. Do I need to lock handles to kernel
>objects when passing them to functions like SetEvent, WaitForSingleObject,
>WaitForMultipleObjects, etc.?
>
>In the actual thread I have done something like this:
>
>// ...
>Lock();
>if(WaitForSingleObject(thread->exitEventHandle, 0) != WAIT_TIMEOUT)
>{
> // the exit event has been set, it's time to shut this thread down
>}
>Unlock();
>
>This probably isn't the most efficient solution, but I don't forsee any problems
>here as far as deadlock is concerned. Where I am concerned about deadlock is in
>the main thread. In the main thread I have a call to WaitForMultipleObjects with
>the timeout set at INFINITE. In my user input thread I have another event
>object. I set this event object whenever the user has given input. This way,
>anytime a thread returns, or a user gives input, the call to
>WaitForMultipleObjects will return and I can handle the information returned
>from the thread, or handle the user input. Here is where I'm concerned with
>deadlock. In the user input thread I'll have something like:
>
>// ...
>Lock();
>SetEvent(inputEventHandle);
>Unlock();
>
>And in my main thread I have:
>
>Lock();
>WaitForMultipleObjects(number, handles, false, INFINITE);
>Unlock();
>// handle whichever object was set
>
>So when the main thread reaches the WaitForMultipleObjects call, it will own the
>lock, and then it will wait for an event to be set. If no search threads are
>running, then they won't cause any events to be set, and so the only remaining
>source of an event being set would be from the user input, and the user input
>thread will never be able to obtain the lock to set it's inputEventHandle
>because the main thread owns the handle...deadlock.
>
>My first idea for a solution to this is to implement the user input thread in
>the same way as other threads, and wait on the input thread to return and handle
>that object being set. I would simply restart the input thread each time input
>was returned, and the call to WaitForMultipleObjects would return nicely.
>
>In other words...
>
>-User input thread gets input from user
>-User input thread stores input in a global variable
>-User input thread returns, setting it's kernel object and causing
>WaitForMultipleObjects to return
>-The main thread can safely access the data that was input from the input thread
>since that thread is no longer running, it handles the input, and restarts the
>input thread, and the process repeats
>
>I'd like to know if I'm doing anything wrong in the initial example, and if my
>second example of restarting the input thread everytime is a good solution or
>not.
>
>Russell
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.