Introduction

We have discussed the nature and generation of processes. In the previous chapter we addressed primitive techniques for communicating between two or more processes. These techniques were limited in scope and suffered from a lack of reliable synchronization. Beginning with this chapter, we explore interprocess communication techniques using system-designed interprocess facilities. We start with pipes , which provide processes with a simple, synchronized way of passing information. By the early 1970s pipes became a standard part of UNIX.

We can think of the pipe as a special file that can store a limited amount of data in a first in, first out (FIFO) manner. On most systems, pipes are limited to a specific size . In Linux, the defined constant PIPE_SIZE (which is usually equivalent to the PAGE_SIZE for the system) establishes the total number of bytes allocated for a pipe. The defined constant PIPE_BUF (found in , which is included by ) sets the block size for an atomic write to a pipe. On our system the value for PIPE_BUF is 4096. Generally, one process writes to the pipe (as if it were a file), while another process reads from the pipe.

As shown in Figure 5.1, conceptually we can envision the pipe as a conveyor belt composed of data blocks that are continuously filled at (written to) the "write end" and emptied (read) from the "read end." The system keeps track of the current location of the last read/write location. Data is written to one end of the pipe and read from the other. From an implementation standpoint, an actual file pointer (as associated with a regular file) is not defined for a pipe, and as such no seeking is supported.

Figure 5.1. Conceptual data access using a pipe.

graphics/05fig01.gif

The operating system provides the synchronization between the writing and reading processes. By default, if a writing process attempts to write to a full pipe, the system automatically blocks the process until the pipe is able to receive the data. Likewise, if a read is attempted on an empty pipe, the process blocks until data is available. In addition, the process blocks if a specified pipe has been opened for reading, but another process has not opened the pipe for writing.

In a program, data is written to the pipe using the unbuffered I/O write system call (Table 5.1).

Table 5.1. Summary of the write System Call.

Include File(s)

Manual Section

2

Summary

ssize_t write(int fd, const void *buf,
size_t count);

Return

Success

Failure

Sets errno

Number of bytes written

-1

Yes

Using the file descriptor specified by fd , the write system call attempts to write count bytes from the buffer referenced by buf . If the write system call is successful, the number of bytes actually written is returned. Otherwise, a 1 is returned and the global variable errno is set to indicate the nature of the error. As shown in Table 5.2, the number of ways in which write can fail is impressive indeed!

Table 5.2. write Error Messages.

#

Constant

perror Message

Explanation

4

EINTR

Interrupted system call

Signal was caught during the system call.

5

EIO

I/O error

Low-level I/O error while attempting read from or write to file system.

6

ENXIO

No such device or address

O_NONBLOCK O_WRONLY is set, the named file is a FIFO, and no process has the file open for reading.

9

EBADF

Bad file descriptor

fd is an invalid file descriptor or is not open for writing.

11

EAGAIN

Resource temporarily unavailable

O_NDELAY or O_NONBLOCK is set and the file is currently locked by another process.

System memory for raw I/O is temporarily insufficient.

Attempted a write to pipe of count bytes, but less than count bytes is available.

14

EFAULT

Bad address

buf references an illegal address.

22

EINVAL

Invalid argument

fd associated with an object unsuitable for writing.

27

EFBIG

File too large

Attempt to write to a file that exceeds the current system limits.

28

ENOSPC

No space left on device

Device with file has run out of room.

32

EPIPE

Broken pipe

Attempt to write to a pipe that is not opened for reading on one end (in this case a SIGPIPE signal also generated).

Attempt to write to a FIFO that is not opened for reading on one end.

Attempt to write to a pipe with only one end open.

34

ERANGE

Numerical result out of range

count value is less than 0 or greater than system limit.

35

EDEADLK

Resource deadlock avoided

The write system call would have gone to sleep generating a deadlock situation.

37

ENOLCK

No locks available

Locking enabled, but region was previously locked.

System lock table is full.

63

ENOSR

Out of streams resources

Attempt to write to a stream, but insufficient stream memory is available.

67

ENOLINK

The link has been severed

The buf value references a remote system that is no longer active.

write s to a pipe are similar to those for a file except that

  • Each file write request is always appended to the end of the pipe.
  • write requests of PIPE_BUF size or less are guaranteed to not be interleaved with other write requests to the same pipe. [1]

    [1] While write may still work if the number of bytes is greater than PIPE_BUF, it is best to stay within this limitation to guarantee the integrity of data.

  • When the O_NONBLOCK and O_NDELAY flags are clear, a write request may cause the process to block. The defined constants O_NONBLOCK and O_NDELAY are included by the header file and can be set with the fcntl system call. By default, these values are considered to be cleared, thus write blocks if the device is busy and write s are delayed (written to an internal buffer, which is written out to disk by the kernel at a later time). Once the write has completed, it returns the number of bytes successfully written.
  • When the O_NONBLOCK or O_NDELAY flags are set and the request to write PIPE_BUF bytes or less is not successful, the value returned by the write system call can be summarized as

    O_NONBLOCK

    O_NDELAY

    Value Returned

    set

    clear

    1

    clear

    set

    If both O_NONBLOCK and O_NDELAY flags are set, write will not block the process.

  • If a write is made to a pipe that is not open for reading by any process, a SIGPIPE signal is generated and the value in errno is set to EPIPE (broken pipe). The default action (if not caught) for the SIGPIPE signal is termination.

Data is read from the pipe using the unbuffered I/O read system call summarized in Table 5.3.

Table 5.3. Summary of the read System Call.

Include File(s)

Manual Section

2

Summary

ssize_t read(int fd, void *buf,
 size_t count);

Return

Success

Failure

Sets errno

Number of bytes read

-1

Yes

The read system call reads count bytes from the open file associated with the file descriptor fd into the buffer referenced by buf . If the read call is successful, the number of bytes actually read is returned. If the number of bytes left in the pipe is less than count , the value returned by read will reflect this. When at the end of the file, a value of 0 is returned. If the read system call fails, a 1 is returned and the global variable errno is set. The values that errno may take when read fails are shown in Table 5.4.

Table 5.4. read Error Messages.

#

Constant

Perror Message

Explanation

4

EINTR

Interrupted system call

Signal was caught during the system call.

5

EIO

I/O error

Background process cannot read from its controlling terminal.

6

ENXIO

No such device or address

File descriptor reference is invalid.

9

EBADF

Bad file descriptor

fd is an invalid file or is not open for reading.

11

EAGAIN

Resource temporarily unavailable

O_NDELAY or O_NONBLOCK is set, and the file is currently locked by another process.

System memory for raw I/O is temporarily insufficient.

O_NDELAY or O_NONBLOCK is set, but there is no data waiting to be read .

14

EFAULT

Bad address

buf references an illegal address.

22

EINVAL

Invalid argument

fd associated with an unsuitable object for reading.

35

EDEADLK

Resource deadlock avoided

The read system call would have gone to sleep generating a deadlock situation.

37

ENOLCK

No locks available

Locking enabled, but region was previously locked.

System lock table is full.

67

ENOLINK

Link has been severed

The buf value references a remote system that is no longer active.

74

EBADMSG

Not a data message

Message to be read is not a data message.

In other aspects, read s performed on a pipe are similar to those on a file except that

  • All reads are initiated from the current position (i.e., no seeking is supported).
  • If both O_NONBLOCK and O_NDELAY flags are clear, then a read system call blocks (by default) until data is written to the pipe or the pipe is closed.
  • If the pipe is open for writing by another process, but the pipe is empty, then a read (in combination with the flags O_NDELAY and O_NONBLOCK) will return the values

    O_NONBLOCK

    O_NDELAY

    Value Returned

    set

    clear

    1

    clear

    set

  • If the pipe is not opened for writing by another process, read returns a 0 (indicating the end-of-file condition). Note, this is the same value that is returned when the O_NDELAY flag has been set, and the pipe is open but empty.

Pipes can be divided into two categories: unnamed pipes and named pipes. Unnamed pipes can be used only with related processes (e.g., parent/child or child/child) and exist only for as long as the processes using them exist. Named pipes actually exist as directory entries. As such, they have file access permissions and can be used with unrelated processes.

Programs and Processes

Processing Environment

Using Processes

Primitive Communications

Pipes

Message Queues

Semaphores

Shared Memory

Remote Procedure Calls

Sockets

Threads

Appendix A. Using Linux Manual Pages

Appendix B. UNIX Error Messages

Appendix C. RPC Syntax Diagrams

Appendix D. Profiling Programs



Interprocess Communication in Linux
Interprocess Communications in Linux: The Nooks and Crannies
ISBN: 0130460427
EAN: 2147483647
Year: 2001
Pages: 136

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net