Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Unleashing anonymous pipes – Part 1

, 19 Aug 2003
Using anonymous pipes for interprocess communication
example1.zip
Example1
Example
Example.dsp
Example.dsw
Example.ncb
Example.plg
Example.opt
example2.zip
Example2
Example2.dsp
Example2.dsw
Example2.ncb
Example2.plg
Debug
Example2.opt
// 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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Dinesh Ahuja

India India
No Biography provided

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 20 Aug 2003
Article Copyright 2003 by Dinesh Ahuja
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid