3. 3
IPC enables one application to control another Application,
and for several applications to share the same data without
interfering with one another. IPC is required in all
multiprocessing systems, but it is not generally supported by
single-process operating systems. The various forms of IPC
that are supported on a UNIX system are as follows :
1) Half duplex Pipes.
2) FIFO’s
3) Full duplex Pipes.
4) Named full duplex Pipes.
5) Message queues.
6) Shared memory.
7) Semaphores.
8) Sockets. 9) STREAMS.
The first seven forms of IPC are usually restricted to IPC
between processes on the same host. The final two i.e. Sockets
and STREAMS are the only two that are generally supported for
IPC between processes on different hosts.
4. Pipes
Pipes have two limitations:
They have been half duplex
These can be used only between processes that have a
common ancestors.
A pipe can be created by calling the pipe function:
Two file descriptors are returned through the filedes:
filedes[0] – open for reading
filedes[1] – open for writing
4
5. The fstat function returns a file type of FIFO for the file
descriptor of either end of a pipe.
We can test for a pipe with the S_IFIFO macro.
Two ways to view a half duplex pipe
5
6. Half – duplex pipe after a fork Pipe from parent to child
6
7. Rules
When one end of the pipe is closed, the following
two rules apply:
If we read from a pipe whose write end has been closed,
read returns 0 to indicate an end of file after all the data
has been read.
If we write to a pipe whose read end has been closed,
the signal SIGPIPE is generated.
If we either ignore the signal or catch it and return from the
signal handler, write returns –1 with errno set to EPIPE.
7
9. popen and pclose Functions
popen and pclose functions will create the pipe, fork a child, closes the
unused end of the pipe, executing a shell to run the command, and waiting
for the command to terminate.
The function popen does a fork and exec to execute the cmdstring, and
returns a standard I/O file pointer.
If type is “r”, the file pointer is connected to the standard output of cmdstring.
If type is “w”, the file pointer is connected to the standard input of cmdstring.
9
10. Result of fp = popen(cmdstring,”w”)
Result of fp = popen(cmdstring,”r”)
10
11. The pclose function closes the standard input
stream, waits for the command to terminate, and
returns the termination status of the shell.
If the shell cannot be executed, the termination
status returned by pclose is as if the shell had
executed exit(127).
11
12. Coprocesses
A UNIX system filter is a program that reads from
standard input and writes to standard output.
A filter becomes a coprocess when the same
program generates the filter's input and reads the
filter's output.
12
13. FIFOs
FIFOs are sometimes called as named pipes.
With FIFOs, unrelated processes can exchange
data.
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t
mode);
The mode argument is same as for the open
function.
13
14. Uses of FIFOs
FIFOs are used by shell commands to pass data
from one shell pipeline to another without creating
intermediate temporary files.
FIFOs are used in client server applications to pass
data between the client and the servers.
14
15. Using FIFOs to Duplicate Output Streams
FIFOs can be used to duplicate an stream in a series
of shell commands.
This prevents writing the data intermediate disk file.
mkfifo fifo1
prog3 < fifo1 &
prog1 < infile | tee fifo1 | prog2
15
19. XSI IPC
Each XSI IPC structure has two ways to identify it
An internal (within the Kernel) non negative integer
identifier
An external key value of type key_t
We must specify a key when we create an XSI IPC
structure. This is converted to an internal identifier
by the Kernel
19
20. Creating Keys
3 ways
Server creates XSI IPC structure with a key of
IPC_PRIVATE and stores the returned internal identifier in
a file for the client to read
Client and Server agree ahead of time on the key.
Requires error handling in case the key is already in use
Client and Server agree on a pathname and project ID
(character value between 0 and 255) and use the ftok
function to convert these two values into a key
20
21. ftok
key_t ftok(const char *pathname, int proj_id);
pathname must be the path to an existing file
proj_id contains a value between 0 and 255
(only lower 8 bits of id are used)
Note that occasionally different pathnames with
the same project id can return the same key!
21
23. Permissions Structure
All fields are initialized when the IPC
structure is created
mode is the same as for the open function
but no execute permission
uid, gid, and mode can be modified with
msgctl, semctl or shmctl
Only the creator of the IPC or root can
change these
23
24. Configuration Limits
All three forms of XSI IPC have built in limits.
Most of these limits can be changed by reconfiguring
the kernel.
24
25. Advantages and Disadvantages
25
A fundamental problem with XSI IPC is that the IPC structures are systemwide and
do not have a reference count. For example, if we create a message queue, place
some messages on the queue, and then terminate, the message queue and its contents
are not deleted. They remain in the system until specifically read or deleted by some
process calling msgrcv or msgctl, by someone executing the ipcrm(1) command, or
by the system being rebooted. Compare this with a pipe, which is completely
removed when the last process to reference it terminates. With a FIFO, although the
name stays in the file system until explicitly removed, any data left in a FIFO is
removed when the last process to reference the FIFO terminates.
Another problem with XSI IPC is that these IPC structures are not known by names
in the file system. We can't access them and modify their properties with the
functions. Almost a dozen new system calls (msgget, semop, shmat, and so on) were
added to the kernel to support these IPC objects. We can't see the IPC objects with
an ls command, we can't remove them with the rm command, and we can't change
their permissions with the chmod command. Instead, two new commands ipcs(1)
and ipcrm(1)were added.
Since these forms of IPC don't use file descriptors, we can't use the multiplexed I/O
functions (select and poll) with them. This makes it harder to use more than one of
these IPC structures at a time or to use any of these IPC structures with file or device
I/O. For example, we can't have a server wait for a message to be placed on one of
two message queues without some form of busywait loop.
26. Message Queues
Similar to FIFO, allows two or more processes to
exchange data.
Not FIFO, messages may be retrieved out of order.
Message queue remains until deleted or system
rebooted.
26
27. Message Queues
Message Queue is a linked lists of messages stored
within the Kernel memory and identified by a message
queue identifier.
Each message queue has its own identifier
Messages within queue can be of different types
Queue opened or created with msgget
New messages added with msgsnd
Messages fetched with msgrcv
27
29. msgget
opens or creates a queue. flag parameter is used to
initialize the mode member of the permission
structure
Returns message queue ID if OK and -1 on error
29
30. 30
The ipc_perm structure is initialized. The mode
member of this structure is set to the corresponding
permission bits of flag.
msg_qnum, msg_lspid, msg_lrpid, msg_stime, and
msg_rtime are all set to 0.
msg_ctime is set to the current time.
msg_qbytes is set to the system limit.
31. msgsnd
msqid internal ID of message queue nbytes size in bytes
of the message flag
OR of zero or more of: IPC_NOWAIT, MSG_NOERROR
ptr points to a long integer that contains the positive
integer message type and it is immediately followed by
the message data
31
32. ptr pointer to the actual message.
Must be of the form
32
33. msgrcv
Retrieves a message from the queue
nbytes is the size in bytes of the text portion of the
structure pointed to by ptr
ptr is a pointer to a structure that will hold the
message retrieved from the queue
33
34. The type argument lets us specify which message
we want.
type == 0 The first message on the queue is returned
type > 0 The first message on the queue whose message type
equals type is returned
type < 0 The first message on the queue whose message type is
the lowest value less than or equal to the absolute value
of type is returned
34
36. The cmd argument specifies the command to be
performed on the queue specified by msqid.
IPC_STAT Fetch the msqid_ds structure for this queue.
IPC_SET Copy the following fields from the structure pointed to by buf to
the msqid_ds structure associated with this queue: msg_perm
and msg_qbytes. Only the superuser can increase the value of
msg_qbytes.
IPC_RMI
D
Remove the message queue from the system and any data still
on the queue. This removal is immediate.
36
37. Semaphores
Semaphore is a counter used to provide access to a shared
resource for multiple processes.
To obtain a shared resource, a process need to do the
following:
Test the semaphore that controls the resource.
If the value of the semaphore is positive, the process can use
the resource.
In this case, the process decrements the semaphore value by 1,
indicating that it has used one unit of the resource.
Otherwise, if the value of the semaphore is 0, the process goes
to sleep until the semaphore value is greater than 0. When the
process wakes up, it returns to step 1.
37
38. When a process is done with shared resource that is
controlled by a semaphore, the semaphore value is
incremented by 1.
If any other processes are asleep, waiting for the
semaphore, they are awakened.
A common form of semaphore is called a binary
semaphore.
It controls a single resource, and its value is initialized to
1.
38
39. The kernel maintains a semid_ds structure for each
semaphore set:
Each semaphore is represented by an anonymous
structure contains at least the following members:
39
40. semget
The ipc_perm structure is initialized.
The mode member of this structure is set to the
corresponding permission bits of flag.
sem_otime is set to 0.
sem _ctime is set to current time.
sem_nsems is set to nsems.
40
41. semctl
The fourth argument is optional, depending on the
command requested, and if present, is of type
semun, a union of various command specific
arguments:
41
42. The cmd argument specifies one of the following ten
commands to be performed on the set specified by
semid.
The five commands that refer to one particular
semaphore value use semnum to specify one
member of the set.
The value of semnum is between 0 and nsems-1.
42
43. IPC_STAT Fetch the semid_ds structure, storing it in the structure pointed to by arg.buf
IPC_SET Set the sem_perm.uid, sem_perm.gid, sem_perm.mode
IPC_RMID Remove the semaphore set from the system. This removal is immediate.
GETVAL Return the value of semval for the member semnum
SETVAL Set the value of semval for the member semnum
GETPID Return the value of sempid for the member semnum
GETNCNT Return the value of semncnt for the member semnum
GETZCNT Return the value of semzcnt for the member semnum
GETALL Fetch all semaphore values in the set. Values stored in array pointed to by
arg.array
SETALL Set all semaphore values in the set to the values pointed to by arg. array
43
44. semop
The semoparray argument is a pointer to an array of semaphore
operations, represented by sembuf structures:
44
45. The nops argument specifies the number of
operations in the array.
The operation on each member of the set is
specified by the corresponding sem_op value.
The value can be negative, 0, or positive.
45
46. Case 1 (sem_op is positive)
This case corresponds to the returning of the
resources by the process.
The value of sem_op is added to the semaphore’s
value.
46
47. Case 2 (sem_op is negative)
If the semaphore’s value is less than the absolute
value of sem_op, the following conditions apply.
If IPC_NOWAIT is specified, semop returns with an error
of EAGAIN.
If IPC_NOWAIT is not specified, the semncnt value for
this semaphore is incremented and the calling process is
suspended until one of the following occurs:
The semaphore value becomes greater than or equal to the
absolute value of sem_op.
The semaphore is removed from the system.
A signal is caught by the process, and the signal handler
returns.
47
48. Case 3 (sem_op is 0)
Means that the calling process wants to wait until the
semaphore value becomes 0.
If the semaphore value is currently 0, the function returns
immediately.
Otherwise,
If IPC_NOWAIT is specified, return is made with an error of
EAGAIN.
If IPC_NOWAIT is not specified, the semzcnt value for this
semaphore is incremented and the calling process is
suspended until one of the following occurs:
The semaphore value becomes 0.
The semaphore is removed from the system.
A signal is caught by the process, and the signal handler returns.
48
49. Shared Memory
Shared memory allows two or more processes to
share a given region of memory.
This is the fastest form of IPC, because the data
does not need to be copied between the client and
the server.
49
50. 50
The kernel maintains a structure with at least the
following members for each shared memory segment:
The type shmatt_t is defined to be an unsigned integer at
least as large as unsigned short.
51. shmget
51
ipc_perm structure is initialized
shm_lpid, shm_nattach, shm_atime, shm_dtime are
all set to 0
shm_ctime is set to the current time
shm_segsz is set to the size requested
52. shmctl
52
The cmd argument specifies one of the following five
commands on the segment specified by shmid:
IPC_STAT Fetch the shmid_ds structure for this segment
IPC_SET Set the shm_perm.uid, shm_perm.gid, and
shm_perm.mode
IPC_RMID Remove the shared memory segment set from the
system
SHM_LOCK Lock the shared memory segment in memory
SHM_UNLOCK Unlock the shared memory segment
53. shmat
53
Once the shared memory segment has been
created, a process attaches it to its address space
by calling shmat.
If addr is 0, the segment is attached at the first available
address selected by the kernel.
If addr is non zero and SHM_RND is not specified, the
segment is attached at the address given by addr.
If addr is non zero and SHM_RND is specified, the
segment is attached at the address given by (addr – (addr
modulus SHMLBA))
SHMLBA – low boundary address multipl
54. shmdt
54
The addr argument is the value that was returned by
a previous call to shmat.
If successful, shmdt will decrement the shm_nattch
counter in the associated shmid_ds structure.
55. Client – Server Properties
55
The simplest type of relationship is to have the client fork
and exec the desired server.
Two half duplex pipes can be created before the fork to allow
data to be transferred in both directions.
With FIFOs, an individual per client FIFO is required if the
server is to send data back to the client. Otherwise a
single well known FIFO is sufficient.
A single message queue can be used between the server
and all the clients, using the type field of each message
to indicate the message recipient OR individual message
queue can also be used for each client.
56. STREAMS – Based Pipes
56
A STREAMS – Based pipe is a bidirectional (full
duplex) pipe.
To obtain bidirectional data flow between a parent
and a child, only a single STREAMS pipe is required.
57. Inside a STREAMS Pipe
57
Inside a STREAMS Pipe
Inside a STREAMS Pipe with a module
58. Naming STREAMS Pipes
58
Normally, pipes can be used only between related
processes: child processes inheriting pipes from
their parent processes.
The STREAMS mechanism provides a way for
processes to give a pipe a name in the file system.
We can use the fattach function to give a STREAMS
pipe a name in the file system.
59. 59
The path argument must refer to an existing file, and the calling
process must either own the file and have write permissions to it or
be running with superuser privileges.
Once the STREAMS pipe is attached to the file system namespace,
the underlying file is inaccessible.
Any process that opens the name will gain access to the pipe, not
the underlying file.
Any processes that had the underlying file open before fattach was
called, can continue to access the underlying file.
61. 61
A process can call fdetach to undo the association
between a STREAMS file and the name in the file
system.
After fdetach is called, any processes that had
accessed the STREAMS pipe by opening the path
will still continue to access the stream, but
subsequent opens of the path will access the original
file residing in the file system.
62. Unique Connections
62
Although we can attach one end of a STREAMS pipe to the
file system namespace, we still have problems if multiple
processes want to communicate with a server using the
named STREAMS pipe.
Data from one client will be interleaved with data from the
other clients writing to the pipe.
With multiple clients reading from the same pipe, we cannot
control which one will be scheduled and actually read what we
send.
The connld STREAMS module solves this problem.
Before attaching a STREAMS pipe to a name in the file system, a
server process can push the connld module on the end of the pipe
that is to be attached.
63. 63
The client process never receives an open file descriptor for the end
of the pipe that it opened.
Instead, the operating system creates a new pipe and returns one
end to the client process as the result of opening /tmp/pipe.
The system sends the other end of the new pipe to the server
process by passing its file descriptor over the existing (attached)
pipe, resulting in a unique connection between the client process and
the server process.
65. 65
With STREAMS pipes, file descriptors are exchanged using two ioctl
commands:
I_SENDFD
I_RECVFD
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
To send a descriptor, we set the third argument for ioctl to the actual
descriptor.
When we receive a descriptor, the third argument for ioctl is a pointer
to a strrecvfd structure:
66. Questions
66
1. Explain how we can communicate with other
process with same ancestors using pipes.
2. Explain coprocesses.
3. What are message queues? Explain the functions
related to message queues.
4. How semaphore is different than message
queues?
5. How shared memory is used to communicate with
two processes?
6. Explain STREAMS based pipes and bring out the
differences between STREAMS pipe and a pipe.