NT provides four types of synchronization objects: critical
sections, semaphores, mutexes, and events: Technically the first three are
all instances of the general semaphore, as discussed in class. The
instance known as Critical_Section is NT's
version of an intra-process binary semaphore. Below are the prototype APIs
that are required followed by an example (I used cut-n-paste, so it does
compile in VC++, with project | setting | C/C++ | code generation |
run-time==multithreaded).
-
- #include <windows.h>
-
- Critical_Section cs;
-
- InitializeCriticalSection( &cs);
/* setup binary semaphore */
- EnterCriticalSection( &cs);
- LeaveCriticalSection( &cs);
- DeleteCriticalSection( &cs);
EXAMPLE: |
- #include <stdio.h>
#include <stdlib.h> /* rand() */
#include <process.h> /* _beginthread */
#include <windows.h> /* CRITICAL_SECTION */
#include <conio.h> /* _getch() */
#define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
#define N
( (int)100)
#define PROTECTED 0
/* yes==1, no==0 */
#if PROTECTED
CRITICAL_SECTION cs;
#endif
int counter=0;
/* shared variable */
bool wait=true;
void CPU( void * delta)
/* simulate a two register CPU */
{
register int reg1, reg2;
#if PROTECTED
EnterCriticalSection( &cs);
/* option to lock area */
#endif
reg1 = (int) delta;
/* cpu register 1 <- copy delta */
reg2 = counter;
/* cpu register 2 <- copy counter */
Sleep( GetRandom(0,10) );
/* simulate random interruts of CPU */
reg2 = reg2 + reg1;
/* register-register addition */
counter = reg2;
/* copy register to RAM */
#if PROTECTED
LeaveCriticalSection( &cs);
/* option to unlock area */
#endif
printf("count is %d\n", counter);
}
void CheckKey( void *dummy )
/* deamon process to look for a pressed */
{ /* key, any key. */
_getch();
wait = false;
}
void main() {
int i, sum = (N*(N-1))/2;
#if PROTECTED
InitializeCriticalSection( &cs);
/* setup binary semaphore */
#endif
_beginthread(CheckKey, 0, NULL);
/* start background thread */
for(i=0; i<N; i++)
_beginthread(CPU, 0, (void *) i);
/* give each CPU marching orders */
while (wait )
/* check if deamon has found a pressed key */
Sleep(100L);
/* take a nap between ... */
printf("totla should be %d, and is computed as %d\n", sum, counter);
}
|