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