/*----------------------------------------------------- Script for AdSense -----------------------------------------------------*/ /* */ /* Footer ----------------------------------------------- */ #footer { clear: both; text-align: center; color: #333333; } #footer .widget { margin:.5em; padding-top: 20px; font-size: 85%; line-height: 1.5em; text-align: left; } /** Page structure tweaks for layout editor wireframe */ body#layout #header { width: 750px; } -->

Friday, April 23, 2010

Thread Synchronization With Kernel Objects:1

In previous post we saw how to synchronize threads using mechanisms that allow your threads to remain in user mode. The wonderful thing about user-mode synchronization is that it is very fast.
While user-mode thread synchronization mechanisms offer great performance, they do have limitations, and for many applications they simply do not work.
1) For example, the interlocked family of functions operates only on single values and never places a thread into a wait state.
2) You can use critical sections to place a thread in a wait state, but you can use them only to synchronize threads contained within a single process.
3) You can easily get into deadlock situations with critical sections because you cannot specify a timeout value while waiting to enter the critical section.


Now lets see how we can synchornize threads using kernel objects.kernel objects are far more versatile than the user-mode mechanisms.the only bad side to kernel objects is their performance.
calling thread must transition from user mode to kernel mode. This transition is costly: it takes about 1000 CPU cycles
For thread synchronization, each of these kernel objects is said to be in a signaled or nonsignaled state. The toggling of this state is determined by rules that Microsoft has created for each object.
For example, process kernel objects are always created in the nonsignaled state. When the process terminates, the operating system automatically makes the process kernel object signaled. Once a process kernel object is signaled, it remains that way forever; its state never changes back to nonsignaled.
A process kernel object is nonsignaled while the process is running, and it becomes signaled when the process terminates.
If you want to write code that checks whether a process is still running, all you do is call a function that asks the operating system to check the process object's Boolean value.
Threads can put themselves into a wait state until an object becomes signaled.
The following kernel objects can be in a signaled or nonsignaled state:
1) Processes
2) Threads
3) Jobs
4) Files
5) Console Input
6) File change notifications
7) Events
8) Waitable timers
9) Semaphores
10) Mutexes

Wait Functions
In my previous experience application development, I was using these wait functions. there wer 6 threads for galileo receiver to run simulteneously and feed the data to the receiver input.
There are two wait functions.
1) Here's an example of how to call WaitForSingleObject with a timeout value other than INFINITE:

DWORD dw = WaitForSingleObject(hProcess, 5000);
switch
(dw) {

case
WAIT_OBJECT_0:
// The process terminated.
break;

case
WAIT_TIMEOUT:
// The process did not terminate within 5000 milliseconds.
break;

case
WAIT_FAILED:
// Bad call to function (invalid handle?)
break;
}


2) example using WaitForMultipleObjects function.

HANDLE h[3];
h[0] = hProcess1;
h[1] = hProcess2;
h[2] = hProcess3;
DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000);
switch
(dw) {
case
WAIT_FAILED:
// Bad call to function (invalid handle?)
break;

case
WAIT_TIMEOUT:
// None of the objects became signaled within 5000 milliseconds.
break;

case
WAIT_OBJECT_0 + 0:
// The process identified by h[0] (hProcess1) terminated.
break;

case
WAIT_OBJECT_0 + 1:
// The process identified by h[1] (hProcess2) terminated.
break;

case
WAIT_OBJECT_0 + 2:
// The process identified by h[2] (hProcess3) terminated.
break;
}


Source: Summary note from my diary (I learnt these concepts long back)

No comments: