ATEasy's internal library contains a full complement of routines for creating, destroying, and altering the priority of threads in ATEasy code.
In order to create a thread, you use the CreateThread function. When a thread is created, it receives a unique identifier called a handle. You use the handle when you refer to the thread. In order to obtain the handle for the current foreground thread, you use the GetCurrentThread function.
Threads are created with different priorities:
aPriorityIdle
aPriorityLowest
aPriorityBelowNormal
aPriorityNormal
aPriorityAboveNormal
aPriorityHighest
aPriorityTimeCritical
You can check the priority of your thread by using the GetThreadPriority function, which requires that you pass it the thread handle. You can set the thread to a different priority by using the SetThreadPriority function. There are also occasions when you would like the thread to come into existence in a suspended state -- for example, when other threads have preparatory work to do which must be completed before the first thread can start. You can do this either by passing a True boolean "Suspended" parameter with the CreateThread function or by suspending the thread from another thread using the SuspendThread function.
Within a thread, you can order that thread to Sleep. Alternatively, you can tell that thread to SuspendThread or ResumeThread from another thread. A possible use for the SuspendThread and ResumeThread would be if one thread were periodically checking the status of a device, but another thread wants to do something with the device without the interference of the first thread; the second thread could tell the first thread to suspend itself and then tell that thread to resume when it was done.
WaitForSingleObject allows a thread to suspend itself until a specific object, such as a synchronization object, gives its signal. In this command, a thread also states how long it is willing to wait for the object. If the object is already available or if it reaches its signal state within the designated time, WaitForSingleObject returns 0 and execution resumes. If the interval passes and the object is still not signaled, the function times out and the thread resumes executing.
The parameter signifying timeout is very important. If for any reason the object never reaches a signaled state, the thread will never resume. Also, if two threads establish a reciprocal infinite wait, they will deadlock.
To make a thread wait for several objects at once, call WaitForMultipleObjects. You can make this function return as soon as any one of the objects becomes available, or you can make it wait until all the requested objects finally reach their signaled states using the boolean bWaitAll parameter. An event-driven program might set up an array of objects that interest it and respond when any of them signals.
ExitThread can be used by an individual thread to gracefully disappear after its work is done. One thread can terminate another thread using the TerminateThread method. However, TerminateThread is somewhat dangerous, in that it does not allow threads to clean up, does not notify attached DLLs, and does not free the initial stack.