Chapter: Multicore Application Programming For Windows, Linux, and Oracle Solaris - Windows Threading

| Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail |

Communicating with Pipes

Pipes are a method of streamed communication where data written to a pipe by one thread can be read from the pipe by a different thread.

Communicating with Pipes

 

Pipes are a method of streamed communication where data written to a pipe by one thread can be read from the pipe by a different thread. Pipes on Windows enable communication between threads within a process, between threads in different processes, or even between threads on different systems.

 

Pipes are available in two flavors. A named pipe can be used to uniquely identify a connection by name. An anonymous pipe does not have an explicit name, so processes wanting to communicate need to obtain its handle. On Windows, anonymous pipes are implemented using a unique name, but this name is not specified by the application when the pipe is created.

 

To create an anonymous pipe, the application should call CreatePipe(). This takes four parameters. The first and second parameters are pointers to the variables to hold the read and write handles for the pipe. The third parameter is the security attributes for the pipe, which, if null, gives the default attributes that do not allow child processes to inherit the handle of the pipe. Passing a pointer to a security attributes object is neces-sary if inheritance of the handle is desired. The fourth parameter is a hint as to the appropriate size of buffer to use for the pipe. A value of zero indicates that the default value should be used.

 

To create a named pipe, an application needs to call CreateNamedPipe(). This cre-ates a pipe and returns a handle to the pipe. The same handle can be used for read or write operations on the pipe, assuming the pipe was set up to allow the operation. This function takes eight parameters; these are listed in Table 6.7.

Table 6.7      Parameters Passed to CreateNamedPipe()


 

Once a pipe has been created, data can be sent through the pipe using the WriteFile() call and read from the pipe using the ReadFile() call. The parameters used in both calls are similar and are shown in Table 6.8.

 

Table 6.8      Parameters Passed to ReadFile() and WriteFile()


 

The pipe must be closed with a call to CloseHandle() once the application has fin-ished using it.

 

Listing 6.30 shows an example of two threads using an anonymous pipe to communi-cate. The pipe is created through a call to CreatePipe() that returns both a read and a write handle for the pipe.

 

Listing 6.30   Using an Anonymous Pipe to Communicate Between Two Threads

#include <windows.h> #include <process.h>

 

HANDLE readpipe,writepipe;

 

unsigned int __stdcall stage1( void * param )

 

{

 

char buffer[200]; DWORD length;

for ( int i=0; i<10; i++ )

 

{

 

sprintf( buffer, "Text %i", i );

 

WriteFile( writepipe, buffer, strlen(buffer)+1, &length, 0 );

 

}

 

CloseHandle( writepipe );

 

return 0;

 

}

 

unsigned int __stdcall stage2( void * param )

 

{

 

char buffer[200]; DWORD length;

while ( ReadFile( readpipe, buffer, 200, &length, 0 ) )

 

{

 

DWORD offset=0;

 

while ( offset<length )

 

{

 

printf( "%s\n", &buffer[offset] ); offset += strlen( &buffer[offset] )+1;

}

 

}

 

CloseHandle( readpipe );

 

return 0;

 

}

 

 

int _tmain( int argc, _TCHAR* argv[] )

 

{

 

HANDLE thread1,thread2;

CreatePipe( &readpipe, &writepipe, 0, 0 );

 

thread1 = (HANDLE)_beginthreadex( 0, 0, &stage1, 0, 0, 0 ); thread2 = (HANDLE)_beginthreadex( 0, 0, &stage2, 0, 0, 0 ); WaitForSingleObject( thread1, INFINITE ); WaitForSingleObject( thread2, INFINITE );

 

getchar(); return 0;

}

The application in Listing 6.30 models a pipeline where one thread does the initial processing before passing the data onto a second thread for more processing. In the code, the first thread places text messages into the pipe using a call to WriteFile(). The sec-ond thread receives and prints out these messages.

 

There is a slight complication in the processing necessary to handle messages placed in a pipe. The pipe is a stream of bytes, so multiple messages become concatenated. The thread that handles the incoming messages must have some additional processing to ensure that all the messages in the buffer are processed before attempting to read the next set of messages. Notice that in this simplified example, the buffer is large enough to hold all the messages sent. In a more realistic example, the receiving thread would have to handle the situation where one message was split between two reads from the pipe.


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.