Here's where you can find example codes on how to deal with various thread implementations in Windows NT for the following topics: threads in general, I/O, and Synchronization.

Threads in General

CreateThread Function:

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpSec, // Security attributes
DWORD dwStack, // Initial size of threads stack
LPTHREAD_START_ROUTINE lpFunc, // Function ptr. of thread to start
LPVOID lpParam, // DWORD param thread receives
DWORD dwFlags, // 0 or CREATE_SUSPEND
LPDWORD lpDwThreadID ); // DWORD ptr to receive thread's ID

Sleep Function:

VOID Sleep( DWORD cMilliseconds ); // sleep time is in milliseconds

WaitForSingleObject Function:

DWORD WaitForSingleObject(

HANDLE hObject, // handle of object to wait for

WORD dwTimeout); // max. time to wait in milliseconds

WaitForMultipleObjects Function

DWORD WaitForMultipleObjects(

DWORD cObjects, // number of handles in handle array

CONST HANDLE * lphObjects, // address of object-handle array

BOOL fWaitAll, // wait flag

DWORD dwTimeout); // time-out interval in milliseconds

Back to Top

I/O Code

m_hdlFile = CreateFile( szFilename, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

// Initialize the OVERLAPPED structure

eventIOComplete =CreateEvent( 0, //Default security
TRUE, // Manual-reset event
FALSE, // Initial stae unsignaled
0);

m_OverlappedStruct.hEvent = eventIOComplete;
m_OverlappedStruct.Offset = 0; // where to start reading
m_OverlappedStruct.OffsetHigh = 0;

// Read from the file asynchronously

bGoodRead = ReadFile(m_hdlFile,
pMemBuffer, // Buffer to read into 512000, read 512k bytes into &wBytesRead, for named pipe I/O
&m_OverlappedStruct );

// If the I/O operation is still pending and the read was not successful

if( ERROR_IO_PENDING == GetLastError() && !bGoodRead ) {
while( bWaitReturn == WAIT_TIMEOUT ) {
// Do some work here .... then
// Check on the completion event
bWaitReturn = WaitForSingleObject ( event IOComplete, 0 );

// Return immediately

}

// Get the number of byte read so you can update the struct

GetOverlappedResult( m_hdlFile,
&m_OverlappedStruct,
&nBytesRead,
FALSE); //Do not wait for I/O to complete

}

// Update the file pointer in the OVERLAPPED struct

m_OverlappedStruct.Offset += wBytesRead;

CloseHandle( m_hdlFile ); // Close the file
CloseHandle( eventIOComplete ); // Close the event

Back to Top

Synchronization Code

Critical Section:

// From winnt.h

typedef struct _RTL_CRITICAL_SECTION {

PRTL_CRITICAL_SECTION_DEBUG DebugInfo;

// The following three fields control entering and exiting the critical section

LONG LockCount;

LONG RecursionCount;

HANDLE OwningThread; // from the thread's ClientId->UniqueThread

HANDLE LockSemaphore;

DWORD Reserved;

} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

// winbase.h

typedec RTL_CRITICAL_SECTION CRITICAL_SECTION;

Use of Critical Section Calls:

void FuncCS() {
EnterCriticalSection( &critSectObj );
if (...)
{
...
LeaveCriticalSection( &critSectObj );
return 0;
}

Read/Write Synchronization: flawed code

// **********************
// * Reader Thread
// **********************

WaitForSingleObject( eventWrite, INFINITE );

++nNumReaders;

if( 1 == nNumReaders ) {
ResetEvent( eventRead ); // Set reader to unsignaled state
}

// *** Do your reading here ***

--nNumReaders;

if( 0 == nNumReaders ) {
SetEvent ( eventRead ); // Set the reader event to signaled state
}

// **********************
// * Writer Thread
// **********************

WaitForSingleObject( eventRead, INFINITE );

// Lock out readers
ResetEvent( eventWrite ); // Set writer to unsignaled state

// *** Do your writing here ***

SetEvent( eventWrite ); // Set the writer event to signaled state

Read/Write Synchronization: Fixed Code

// **********************
// * Reader Thread
// **********************

WaitForSingleObject( mutexRead, INFINITE );

++nNumReaders;

if( 1 == nNumReaders ) {
// Wait for any write threads to finish writing

WaitForSingleObject( mutexWrite, INFINITE);
}

ReleaseMutex( mutexRead );

// *** Do your reading here ***

WaitForSingleObject( mutexRead, INFINITE );

--nNumReaders;

if( 0 == nNumReaders ) {
ReleaseMutex( mutexWrite ); // Set the writer mutex to signaled state
}

ReleaseMutex( mutexRead);

// **********************
// * Writer Thread
// **********************

WaitForSingleObject( mutexWrite, INFINITE );

// *** Do your writing here ***

ReleaseMutex( mutexWrite ); // Set the writer mutex to signaled state

Back to Top

Windows NT