|
// This is an example which shows how the writer thread
// and a reader thread, within the same process interacts
// with each other. There is a synchronization between two
// threads i.e. when writer thread writes, the reader thread
// will sleep and vice-versa.
// The code has been developed and tested on WIN-98.
// Code by Dinesh Ahuja, Aug 09, 2003.
#include <windows.h>
#include <assert.h>
#include <stdio.h>
// specifies the Buffer size for the pipe.
#define PIPE_BUFFERLENGTH 19
// Structure which encapsulates the data to be transferred from the
// writer thread to the reader thread.
struct ThreadData {
HANDLE hWrThread;
HANDLE hRdPipe;
};
// Reader thread function.
void ThreadFunc(LPVOID lpVoid) {
HANDLE hReadPipe = ((ThreadData*)lpVoid)->hRdPipe;
HANDLE hWrThread = ((ThreadData*)lpVoid)->hWrThread;
// Reading data from pipe.
for(int i=0;i<50;i++) {
char ReadBuff[50] = {'\0'};
BOOL bRet = FALSE;
DWORD dwRead;
if((i>=0) && (i<=9)) {
bRet = ReadFile(hReadPipe,&ReadBuff,18,&dwRead,NULL);
}
else {
bRet = ReadFile(hReadPipe,&ReadBuff,19,&dwRead,NULL);
}
if(bRet == FALSE) {
assert(bRet != FALSE);
break;
}
printf("Thread has Read :%s",ReadBuff);
if( (dwRead == 18) || (dwRead == 19)) {
// This acts as a toggle between the reader thread and a
// writer thread.
ResumeThread(hWrThread);
SuspendThread(GetCurrentThread());
}
}
CloseHandle(hReadPipe);
ExitThread(0);
}
int main() {
HANDLE hReadPipe = NULL; // Handle to a read end of a pipe.
HANDLE hWritePipe = NULL; // Handle to a write end of a pipe.
HANDLE hRdThread = NULL; // Handle to a reader thread.
BOOL bReturn = FALSE;
DWORD dwThreadID; // Thread ID.
HANDLE hWrThread = NULL; // Handle to a writer thread.
HANDLE hWrDupl = NULL; // Duplicate handle to a writer
// thread.
ThreadData thdData; // Data to be sent to Reader thread.
// Creates an unnamed pipe.
bReturn = CreatePipe(&hReadPipe,&hWritePipe,NULL,PIPE_BUFFERLENGTH);
if (bReturn != FALSE) {
// Storing a handle to a read end of a pipe into the
// ThreadData's data member.
thdData.hRdPipe = hReadPipe;
/* The main thread is a writer thread, so we are retrieving
** the Pseudo handle for the current thread.
*/
hWrThread = GetCurrentThread();
/* The handle returned by the GetCurrentThread can't be
** used by anyother thread. A thread can create a compatible
** handle to itself, which can be used by other threads, by
** calling DuplicateHandle with the Pseudo handle as an
** argument.
*/
bReturn = DuplicateHandle(GetCurrentProcess(),hWrThread,GetCurrentProcess(),&hWrDupl,NULL,FALSE,DUPLICATE_SAME_ACCESS);
// Storing a handle to a write thread into the ThreadData's
// data member.
thdData.hWrThread = hWrDupl;
if (bReturn != FALSE) {
// Creates a reader thread, which act as a pipe client and
// passing the ThreadData structure to the reader thread.
hRdThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)&thdData,CREATE_SUSPENDED,&dwThreadID);
// Writing data on the pipe.
for(int i=0;i<50;i++) {
char Buff[50] = {'\0'};
int len;
DWORD dwWrite; // Actual data written to the pipe.
BOOL bRet = FALSE;
len = wsprintf(Buff,"This is line no:%i\n",i);
bRet = WriteFile(hWritePipe,Buff,len,&dwWrite,NULL);
assert(bRet != NULL);
/* The size of the data which could be written on the
** pipe can be of 18 or 19 bytes.
*/
if( (dwWrite == 18) || (dwWrite == 19)) {
// These two functions acts as a toggle between the
// the reader and a writer thread.
ResumeThread(hRdThread);
SuspendThread(GetCurrentThread());
}
}
}
CloseHandle(hWritePipe);
// Wait for reader thread to finish its work and exit itself.
WaitForSingleObject(hRdThread,INFINITE);
}
else {
assert(bReturn != FALSE);
}
return 0;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.