Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
  Previous   Contents   Next 
   
 
Chapter 5

Interprocess Communication

This chapter is for programmers who develop multiprocess applications.

SunOS 5.9 and compatible operating environments have a large variety of mechanisms for concurrent processes to exchange data and synchronize execution. All of these mechanisms, except mapped memory, are introduced in this chapter.

Pipes Between Processes

A pipe between two processes is a pair of files that is created in a parent process. The pipe connects the resulting processes when the parent process forks. A pipe has no existence in any file name space, so it is said to be anonymous. A pipe usually connects only two processes, although any number of child processes can be connected to each other and their related parent by a single pipe.

A pipe is created in the process that becomes the parent by a call to pipe(2). The call returns two file descriptors in the array passed to it. After forking, both processes read from p[0] and write to p[1]. The processes actually read from and write to a circular buffer that is managed for them.

Because calling fork(2) duplicates the per-process open file table, each process has two readers and two writers. Closing the extra readers and writers enables the proper functioning of the pipe. For example, no end-of-file indication would ever be returned if the other end of a reader is left open for writing by the same process. The following code shows pipe creation, a fork, and clearing the duplicate pipe ends.

#include <stdio.h>
#include <unistd.h>
 ...
 	int p[2];
 ...
 	if (pipe(p) == -1) exit(1);
 	switch( fork() )
 	{
 		case 0:						/* in child */
 			close( p[0] );
 			dup2( p[1], 1);
 			close P[1] );
 			exec( ... );
 			exit(1);
 		default:						/* in parent */
 			close( p[1] );
 			dup2( P[0], 0 );
 			close( p[0] );
 			break;
 	}
 	...

The following table shows the results of reads from a pipe and writes to a pipe, under certain conditions.

Table 5-1 Read/Write Results in a Pipe

Attempt

Conditions

Result

read

Empty pipe, writer attached

Read blocked

write

Full pipe, reader attached

Write blocked

read

Empty pipe, no writer attached

EOF returned

write

No reader

SIGPIPE

Blocking can be prevented by calling fcntl(2) on the descriptor to set FNDELAY. This causes an error return (-1) from the I/O call with errno set to EWOULDBLOCK.

Named Pipes

Named pipes function much like pipes, but are created as named entities in a file system. This enables the pipe to be opened by all processes with no requirement that they be related by forking. A named pipe is created by a call to mknod(2). Any process with appropriate permission can then read or write to a named pipe.

In the open(2) call, the process opening the pipe blocks until another process also opens the pipe.

To open a named pipe without blocking, the open(2) call joins the O_NDELAY mask (found in sys/fcntl.h) with the selected file mode mask using the Boolean or operation on the call to open(2). If no other process is connected to the pipe when open(2) is called, -1 is returned with errno set to EWOULDBLOCK.

Sockets

Sockets provide point-to-point, two-way communication between two processes. Sockets are a basic component of interprocess and intersystem communication. A socket is an endpoint of communication to which a name can be bound. It has a type and one or more associated processes.

Sockets exist in communication domains. A socket domain is an abstraction that provides an addressing structure and a set of protocols. Sockets connect only with sockets in the same domain. Twenty three socket domains are identified (see sys/socket.h), of which only the UNIX and Internet domains are normally used in Solaris 9 and compatible operating environments.

You can use sockets to communicate between processes on a single system, like other forms of IPC. The UNIX domain (AF_UNIX) provides a socket address space on a single system. UNIX domain sockets are named with UNIX paths. UNIX domain sockets are further described in "UNIX Domain Sockets" in Network Interface Guide. Sockets can also be used to communicate between processes on different systems. The socket address space between connected systems is called the Internet domain (AF_INET). Internet domain communication uses the TCP/IP internet protocol suite. Internet domain sockets are described in "Socket Interfaces" in Network Interface Guide.

POSIX Interprocess Communication

POSIX interprocess communication (IPC) is a variation of System V interprocess communication. It was introduced in the Solaris 7 release. Like System V objects, POSIX IPC objects have read and write, but not execute, permissions for the owner, the owner's group, and for others. There is no way for the owner of a POSIX IPC object to assign a different owner. POSIX IPC includes the following features:

  • Messages allow processes to send formatted data streams to arbitrary processes.

  • Semaphores allow processes to synchronize execution.

  • Shared memory allows processes to share parts of their virtual address space.

Unlike the System V IPC interfaces, the POSIX IPC interfaces are all multithread safe.

POSIX Messages

The POSIX message queue interfaces are listed in the following table.

Table 5-2 POSIX Message Queue Interfaces

Interface Name

Purpose

mq_open(3RT)Connects to, and optionally creates, a named message queue 
mq_close(3RT)Ends the connection to an open message queue 
mq_unlink(3RT)Ends the connection to an open message queue and causes the queue to be removed when the last process closes it 
mq_send(3RT)Places a message in the queue 
mq_receive(3RT)Receives (removes) the oldest, highest priority message from the queue 
mq_notify(3RT)Notifies a process or thread that a message is available in the queue 
mq_setattr(3RT), mq_getattr(3RT)Set or get message queue attributes 

POSIX Semaphores

POSIX semaphores are much lighter weight than are System V semaphores. A POSIX semaphore structure defines a single semaphore, not an array of up to 25 semaphores.

The POSIX semaphore interfaces are shown below.

Table 5-3 POSIX Semaphore Interfaces

sem_open(3RT)

Connects to, and optionally creates, a named semaphore

sem_init(3RT)

Initializes a semaphore structure (internal to the calling program, so not a named semaphore)

sem_close(3RT)

Ends the connection to an open semaphore

sem_unlink(3RT)

Ends the connection to an open semaphore and causes the semaphore to be removed when the last process closes it

sem_destroy(3RT)

Initializes a semaphore structure (internal to the calling program, so not a named semaphore)

sem_getvalue(3RT)

Copies the value of the semaphore into the specified integer

sem_wait(3RT), sem_trywait(3RT)

Blocks while the semaphore is held by other processes or returns an error if the semaphore is held by another process

sem_post(3RT)

Increments the count of the semaphore

 
 
 
  Previous   Contents   Next