Transcript PPT
Inter Process Communication
Introduction
• Traditionally describe mechanism for
message passing between different
processes that are running on some
operating system.
IPC
• Mechanism for processes to communicate and to
synchronize their actions.
• Message system – processes communicate with each
other without resorting to shared variables.
• IPC facility provides two operations:
– send(message) – message size fixed (signals) or variable
(sockets)
– receive(message)
• If P and Q wish to communicate, they need to:
– establish a communication link between them (connection
oriented e.g. TCP/IP, pipe)
– exchange messages via send/receive (e.g. UDP/IP)
• Implementation of communication link
– physical (e.g., shared memory, hardware bus, network)
– logical (e.g., logical properties: FIFO, error free)
Direct Communication
• Processes must name each other explicitly:
– send (P, message) – send a message to process P
– receive(Q, message) – receive a message from
process Q
• Properties of communication link
– Links are established automatically.
– A link is associated with exactly one pair of
communicating processes.
– The link may be unidirectional (e.g. signaling), but is
usually bi-directional (e.g. sockets).
Indirect Communication
• Messages are directed and received from
mailboxes (also referred to as ports).
– Each mailbox has a unique id. (e.g. shared memory,
shared file, message Q)
– Processes can communicate only if they share a
mailbox.
• Properties of communication link
– A link may be associated with many processes.
– Each pair of processes may share several
communication links.
– Link may be unidirectional or bi-directional.
Indirect Communication
• Operations
– create a new mailbox
– send and receive messages through mailbox
– destroy a mailbox
• Primitives are defined as:
send(A, message) – send a message to
mailbox A
receive(A, message) – receive a message
from mailbox A
Synchronization
• Message passing may be either blocking or nonblocking.
• Blocking is considered synchronous
• Non-blocking is considered asynchronous
• send and receive primitives may be either
blocking or non-blocking.
• Buffering: Queue of messages attached to the
link; implemented usually with bounded
capacity.
finite length of n messages. Sender must wait if link
full.
Persistence
• Persistence: How long an IPC object of that type
remains in existence.
– Process persistence IPC
(socket)
– Kernel persistence IPC
(message Q)
– File-System persistence IPC (shared file)
Examples
Direct Communication
Signals
• The source process can "raise" a signal and
have it delivered to destination process. The
destination process' signal handler is invoked
and the process can handle it.
– A direct communication
– Unidirectional channel is established automatically.
– Processes must name each other explicitly using the
process ID in order to send messages of fixed size.
– Asynchronous.
– Kernel persistence (e.g. SIGCHILD).
Pipes
• There is no form of IPC that is simpler than pipes.
– A direct communication in which unidirectional
channels are established between “related” processes.
– Basically, a call to the int pipe(int fd[2])
function returns a pair of file descriptors.
– One of these descriptors is connected to the write end
of the pipe, and the other is connected to the read end.
– On many systems, pipes will fill up after you write
about 10K to them without reading anything out.
#include
#include
#include
#include
Example
<stdio.h>
<stdlib.h>
<sys/types.h>
<unistd.h>
int main() {
int pfds[2];
char buf[30];
pipe(pfds);
if (fork()==0) {
printf(" CHILD: writing to the pipe\n");
write(pfds[1], "test", 5); //close pfds[0]
printf(" CHILD: exiting\n");
exit(0);
} else {
printf("PARENT: reading from pipe\n");
read(pfds[0], buf, 5); //close pfds[1]
printf("PARENT: read \"%s\"\n", buf);
wait(NULL);
}
}
"ls | wc –l”
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int pfds[2];
pipe(pfds);
if (!fork()) {
close(1);
/*
dup(pfds[1]);
/*
close(pfds[0]); /*
execlp("ls", "ls",
} else {
close(0);
/*
dup(pfds[0]);
/*
close(pfds[1]); /*
execlp("wc", "wc",
}
return 0;
}
close normal stdout */
make stdout same as pfds[1] */
we don't need this */
NULL);
close normal stdin */
make stdin same as pfds[0] */
we don't need this */
"-l", NULL);
FIFO
• A FIFO is sometimes known as a named pipe. That is,
it's like a pipe, except that it has a name!
• In this case, the name is that of a file that multiple
processes can open and read and write to.
• Has to be open at both ends simultaneously before you
can proceed to do any input or output operations on it .
• Would you like to know more?
– int mkfifo(const char *path,
mode_t mode);
– mkfifo("/tmp/namedpipe" , 0666);
– SIGPIPE
Producer
int main(void)
{
char s[300];
int num, fd;
mkfifo("/tmp/namedpipe" , 0666);
printf("waiting for readers...\n");
fd = open("/tmp/namedpipe", O_WRONLY); //blocked
printf("got a reader--type some stuff\n");
while (gets(s), !feof(stdin)) {
if ((num = write(fd, s, strlen(s))) == -1)
perror("write");
else
printf(“producer: wrote %d bytes\n", num);
}
return 0;
}
Consumer
int main(void)
{
char s[300];
int num, fd;
mkfifo ("/tmp/namedpipe", 0666);
printf("waiting for writers...\n");
fd = open("/tmp/namedpipe", O_RDONLY);
printf("got a writer\n");
do {
if ((num = read(fd, s, 300)) == -1)
perror("read");
else {
s[num] = '\0';
printf(“consumer: read %d bytes: \"%s\"\n",
num, s);
}
} while (num > 0);
return 0;
}
Examples
Indirect Communication
Message Queues
• Create:
int msgget(key_t key, int msgflg);
key_t ftok(const char *path, int id);
key = ftok(“somefile", 'b');
msqid = msgget(key, 0666 | IPC_CREAT);
• Send
int msgsnd(int msqid, const void *msgp, size_t
msgsz, int msgflg =0);
• Receive:
int msgrcv(int msqid, void *msgp, size_t msgsz,
long msgtyp, int msgflg);
• Destroy:
int msgctl(int msqid, int cmd, struct msqid_ds
*buf);
msgctl(msqid, IPC_RMID, NULL);
Example
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct my_msgbuf {
long mtype;
char mtext[200];
};
Producer
int main(void)
{
struct my_msgbuf buf;
int msqid;
key_t key;
key = ftok("ipc_example.c", 'B');
msqid = msgget(key, 0644 | IPC_CREAT);
printf("Enter lines of text, ^D to quit:\n");
buf.mtype = 1;
while(gets(buf.mtext), !feof(stdin)) {
msgsnd(msqid, (struct msgbuf *)&buf,
strlen(buf.mtext)+1, 0);
}
msgctl(msqid, IPC_RMID, NULL);
return 0;
}
Consumer
int main(void)
{
struct my_msgbuf buf;
int msqid;
key_t key;
key = ftok("ipc_example.c", 'B');
msqid = msgget(key, 0644);
for(;;) {
msgrcv(msqid, (struct msgbuf *)&buf,
sizeof(buf.mtext), 0, 0);
printf("consumer: \"%s\"\n", buf.mtext);
}
return 0;
}
Shared Memory Segments
• Create:
int shmget(key_t key, size_t size, int shmflg);
key = ftok(“somefile", ‘b');
shmid = shmget(key, 1024, 0644 | IPC_CREAT);
• Use:
void *shmat(int shmid, void *shmaddr, int shmflg);
int shmdt(void *shmaddr);
• Destroy:
shmctl(shmid, IPC_RMID, NULL);
For synchronization use UNIX semaphores.