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
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
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 writingWaitForSingleObject( 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