Each process parent and child should first close the ends of the pipe that they

Each process parent and child should first close the

This preview shows page 83 - 88 out of 236 pages.

Each process ( parent and child ) should first close the ends of the pipe that they are not using. For example, if the parent is writing to the pipe and the child is reading, then the parent should close the reading end of its pipe after the fork and the child should close the writing end. Figure 3.22 shows an ordinary pipe in UNIX, and Figure 3.23 shows code in which it is used. Figure 3.24
Image of page 83
79 Figure 3.25 and Figure 3.26 Ordinary pipes in Windows are very similar o Windows terms them anonymous pipes o They are still limited to parent-child relationships. o They are read from and written to as files.
Image of page 84
80 o They are created with CreatePipe( ) function, which takes additional arguments. o In Windows it is necessary to specify what resources a child inherits, such as pipes. Figure 3.27 and Figure 3.28
Image of page 85
81 Figure 3.29 3.6.3.2 Named Pipes Named pipes support bidirectional communication, communication between non parent-child related processes, and persistence after the process which created them exits. Multiple processes can also share a named pipe, typically one reader and multiple writers. In UNIX, named pipes are termed fifos, and appear as ordinary files in the file system. o ( Recognizable by a "p" as the first character of a long listing, e.g. /dev/initctl ) o Created with mkfifo( ) and manipulated with read( ), write( ), open( ), close( ), etc. o UNIX named pipes are bidirectional, but half-duplex, so two pipes are still typically used for bidirectional communications. o UNIX named pipes still require that all processes be running on the same machine. Otherwise sockets are used. Windows named pipes provide richer communications. Full-duplex is supported. Processes may reside on the same or different machines Created and manipulated using CreateNamedPipe( ), ConnectNamedPipe( ), ReadFile( ),and WriteFile( ). Race Conditions ( Not from the book ) Any time there are two or more processes or threads operating concurrently, there is potential for a particularly difficult class of problems known as race conditions. The identifying characteristic of race conditions is that the performance varies depending on which process or thread executes their instructions before the other one, and this becomes a problem when the program runs correctly in some instances and incorrectly in others.
Image of page 86
82 Race conditions are notoriously difficult to debug, because they are unpredictable, unrepeatable, and may not exhibit themselves for years. Here is an example involving a server and a client communicating via sockets: 1. First the server writes a greeting message to the client via the socket: const int BUFFLENGTH = 100; char buffer[ BUFFLENGTH ]; sprintf( buffer, "Hello Client %d!", i ); write( clientSockets[ i ], buffer, strlen( buffer ) + 1 ); 2. The client then reads the greeting into its own buffer. The client does not know for sure how long the message is, so it allocates a buffer bigger than it needs to be. The following will read all available characters in the socket, up to a maximum of BUFFLENGTH characters: const int BUFFLENGTH = 100; char buffer[ BUFFLENGTH ]; read( mysocket, buffer, BUFFLENGTH );
Image of page 87
Image of page 88

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture