Interprocess Communication n Networking involves communication between processes. n Not all interprocess communication involves networking. n Typically, IPC services are provided by the Operating System. IPC - Single System IPC - Different Systems Single System IPC n Pipe: one-way data stream n FIFO: special kind of pipe n Message Queue: message passing (not a data stream) n Semaphores: Synchronization primitive n Shared Memory: data does not go through the kernel (Operating System). File Locking n Allows cooperating processes to share a resource safely (mutual exclusion). n Example: Ð integer count kept in a file Ð the count is updated by a program every time some event occurs Ð without file locking the value can be corrupted. Advisory vs. Mandatory Locking n Advisory - operating system keeps track of file locks but does not enforce access restrictions. Requires cooperating processes. n Mandatory - operating system checks every read and write, withholding services when appropriate. Record Locking n Lock part of a file, in Unix this typically means a range of character positions within the file. n Multiple processes can use the same file at the same time as long as they are working on different parts of the file. lockf() sytem call (Sys V) n Single system call for all file locking services: Ð lock a region of a file Ð unlock a region of a file Ð test and lock a region (non-blocking) Ð test to see if a region is locked Blocking vs. Non-Blocking System Calls Blocking - system call does not return until the requested operation is possible (or an error occurs). The calling process is put to sleep until the operation is possible. Non-Blocking - system call returns if the operation is not possible immediately. There must be some way for the calling process to determine what happened ! Back to lockf() int lockf( int fd, int function, long size) fd is a file descriptor (small integer) function can be: F_ULOCK unlock a region F_LOCK lock a region (blocking) F_TLOCK lock a region (non-blocking) F_TEST test a region (blocking) lockf() example /* lock a file */ if ( lockf(file, F_LOCK, 0) == -1 ) /* error - canÕt lock the file */ /* unlock a file */ if ( lockf(file, F_ULOCK, 0) == -1 ) /* error - canÕt unlock the file */ POSIX file locking n POSIX supports advisory file locking. n All file locking services provided via the fcntl() system call. n Additional services (beyond lockf): Ð shared locks (read locks) Ð can find out what process has a lock (pid) Pipes n One-way stream of data n Kernel buffers the data pipe() system call int pipe( int filedes[2]) n filedes is a 2 element array of file descriptors - pipe fills in the values. n return value is less than 0 if an error occurred. pipe() pipe() followed by fork() Cleanup with close() 2-way communication n Need 2 pipes to support 2-way communication between parent process and child process. n Both pipes must be created before the fork() Creating 2-way communication int fd_a[1], fd_b[2]; if ( (pipe(fd_a)<0) || (pipe(fd_b)<0) ) /* error opening pipes */ if (fork()==0){ /* child process */ close(fd_a[0]); close(fd_b[1]); /* write to parent via fd_a[1], read from fd_b[0] */ } else { /* parent process */ close(fd_a[1]); close(fd_b[0]); /* write to child via fd_b[1], read from fd_a[0] */ } 2-way communication IPC using pipes n Processes must be closely related (must have a common ancestor). n Unix shells use pipes extensively to pass the output of one process as input to another process. ls | sort | more FIFOs First In, First Out n Also known as Named Pipe n Data stream buffered by the kernel n A FIFO has a name associated with it - this makes IPC between independent processes possible. n The name is a Unix pathname. mknod() system call n A FIFO is created with the mknod() system call. int mknod(char *pathname,int mode,int dev) n pathname is a Unix pathname n mode specifies the access mode (permissions) n dev is ignored (mknod is used for other things) opening a FIFO n the open() system call is used to open a FIFO for reading or writing. n opening a FIFO for reading will block until a process opens the FIFO for writing. n opening a FIFO for writing will block until a process opens the FIFO for reading. n Use the O_NDELAY flag when opening a FIFO to avoid the problem (O_NONBLOCK for POSIX). Rules for reading FIFOs & Pipes n any read() requesting more data than exists in the FIFO (pipe) returns less than the requested amount of data. n read from empty FIFO (pipe) returns: Ð 0 if no process has the FIFO (pipe) open for writing - End-of-File condition. Ð If non-blocking mode is set - read() returns a 0 whenever there is no data availble. Rules for writing FIFOs & Pipes n writes of less than the capacity of the FIFO (pipe) are atomic. n a write to a FIFO or pipe wich is not open for reading by any process generate a SIGPIPE and write() returns an error. n a write to a full FIFO or pipe will block (unless non-blocking mode). Streams vs. Messages n Stream I/O Ð no record boundaries Ð reading process cannot tell how bytes were written (how many bytes at a time). Ð O.S. does buffering Ð Any structure to the data must be supported by the application Streams vs. Messages n Message based I/O: Ð structured data Ð each read corresponds to a write Ð depending on the message service, the order of messages may not be preserved. System V IPC n The book describes Sys V message queues, semaphores and shared memory. n We wonÕt cover this material n Could be a case study: Ð Review Sys V IPC programming interface Ð describe how it could be done with a network. FIFO Example n Client - Server architecture n Need 2 FIFOs for 2-way communication n Server accessible via Òwell knownÓ address (FIFO pathname). n Client creates FIFO and sends server the name. FIFO Example Server 1. opens well known FIFO (fifo_wk) for reading. 2. reads name of temporary FIFO (fifo_tmp) from fifo_wk. 3. opens fifo_tmp for writing. 4. receives request from fifo_wk and sends response to fifo_tmp. 5. close fifo_tmp and go back to step 1. Client 1. create temporary FIFO fifo_tmp. 2. open well known FIFO fifo_wk for writing. 3. write name of temporary FIFO to fifo_wk. 4. open fifo_tmp for reading. 5. write request to fifo_wk 6. read response from fifo_tmp. 7. close FIFOs and delete fifo_tmp. Deadlock n By default, an open() call to a FIFO will block. n The order of open() calls is important !!! n Can avoid some problems with O_NONBLOCK option to open(): fd = open(path, O_NONBLOCK | O_RDONLY); Homework #1 n Develop a FIFO based Client-Server system for looking up uids. n Client sends the server a login name (the request). n Server sends back a uid (the response). Homework #1 (cont.) n Server uses a well known FIFO. n You can create the well known FIFO with the Unix command /etc/mknod. n Test the well known FIFO with the Unix cat command. n Use the code in the book as a starting point.