Click here to Skip to main content
15,891,529 members
Articles / Programming Languages / C++

Unleashing anonymous pipes – Part 1

Rate me:
Please Sign up or sign in to vote.
4.08/5 (17 votes)
19 Aug 20037 min read 101.6K   4.1K   39  
Using anonymous pipes for interprocess communication
// 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


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions