Chapter 15 Interprocess Communication System Programming http ecourse

  • Slides: 80
Download presentation
Chapter 15. Interprocess Communication System Programming http: //ecourse. elearning. ccu. edu. tw/ 熊博安 國立中正大學資訊

Chapter 15. Interprocess Communication System Programming http: //ecourse. elearning. ccu. edu. tw/ 熊博安 國立中正大學資訊 程學系 pahsiung@cs. ccu. edu. tw (05)2720411 ext. 33119 Class: EA-205 Office: EA-512 Textbook: Advanced Programming in the UNIX Environment, 2 nd Edition, W. Richard Stevens and Stephen A. Rago 1

Summary of UNIX System IPC type Half-duplex pipes FIFOs SUS Free. BSD 5. 2.

Summary of UNIX System IPC type Half-duplex pipes FIFOs SUS Free. BSD 5. 2. 1 Linux 2. 4. 22 Mac OS X 10. 3 Solaris 9 (full) • • • (full) • Full-duplex pipes Allowed Named full-duplex pipes XSI option • , UDS Opt, UDS UDS • , UDS Message queues Semaphores Shared memory XSI XSI • • • Sockets STREAMS • XSI option • • opt • • • Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan • • 2

Contents n pipes n FIFOs n message queues n semaphores n shared memory Slides©

Contents n pipes n FIFOs n message queues n semaphores n shared memory Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 3

Pipes n n Oldest form of UNIX System IPC 2 Limitations of pipes: n

Pipes n n Oldest form of UNIX System IPC 2 Limitations of pipes: n Historically, half-duplex (only 1 -direction data flow) n n n Modern OS, full-duplex (never assume this!) Must have a common ancestor (no names!) Still the most common form of IPC n Shells use pipes between two processes Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 4

Pipes n Process creates a pipe, forks, and uses the pipe to communicate with

Pipes n Process creates a pipe, forks, and uses the pipe to communicate with child #include <unistd. h> int pipe (int fildes[2]); n Returns: 0 if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 5

Pipes n n Half-duplex pipes n filedes[0]: open for reading n filedes[1]: open for

Pipes n n Half-duplex pipes n filedes[0]: open for reading n filedes[1]: open for writing n Output of filedes[1] is input of filedes[0] Full-duplex pipes n filedes[0], filedes[1]: open for both reading and writing Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 6

Pipes Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 7

Pipes Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 7

Half-duplex pipes after fork Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng

Half-duplex pipes after fork Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 8

Pipe (Parent Child) Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University,

Pipe (Parent Child) Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 9

Pipes n Read from a pipe with write end closed: n n n Write

Pipes n Read from a pipe with write end closed: n n n Write to a pipe with read end closed: n n n if data, data is read, and when no data, returns 0 ( EOF) SIGPIPE generated, write() returns -1 with errno = EPIPE_BUF: #bytes in kernel’s pipe buffer size (no interleaving when write size PIPE_BUF) Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 10

Figure 15. 5: Parent Child Pipe #include “apue. h" int main(void) { int n,

Figure 15. 5: Parent Child Pipe #include “apue. h" int main(void) { int n, fd[2]; pid_t pid; char line[MAXLINE]; if (pipe(fd) < 0) err_sys("pipe error"); if ( (pid = fork()) < 0) err_sys("fork error"); else if (pid > 0) { /* parent */ close(fd[0]); write(fd[1], "hello worldn", 12); } else { /* child */ close(fd[1]); n = read(fd[0], line, MAXLINE); write(STDOUT_FILENO, line, n); } exit(0); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 11

Figure 15. 6: pipe more #include <sys/wait. h> “apue. h" #define DEF_PAGER "/bin/more" /*

Figure 15. 6: pipe more #include <sys/wait. h> “apue. h" #define DEF_PAGER "/bin/more" /* default pager program */ int main(int argc, char *argv[]) { int n, fd[2]; pid_t pid; char line[MAXLINE], *pager, *argv 0; FILE *fp; if (argc != 2) err_quit("usage: a. out <pathname>"); Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 12

Figure 15. 6: pipe more if ( (fp = fopen(argv[1], "r")) == NULL) err_sys("can't

Figure 15. 6: pipe more if ( (fp = fopen(argv[1], "r")) == NULL) err_sys("can't open %s", argv[1]); if (pipe(fd) < 0) err_sys("pipe error"); if ( (pid = fork()) < 0) err_sys("fork error"); else if (pid > 0) { /* parent */ close(fd[0]); /* close read end */ /* parent copies argv[1] to pipe */ while (fgets(line, MAXLINE, fp) != NULL) { n = strlen(line); if (write(fd[1], line, n) != n) err_sys("write error to pipe"); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 13

Figure 15. 6: pipe more if (ferror(fp)) err_sys("fgets error"); close(fd[1]); /* close write end

Figure 15. 6: pipe more if (ferror(fp)) err_sys("fgets error"); close(fd[1]); /* close write end of pipe for reader */ if (waitpid(pid, NULL, 0) < 0) err_sys("waitpid error"); exit(0); } else { /* child */ close(fd[1]); /* close write end */ if (fd[0] != STDIN_FILENO) { if (dup 2(fd[0], STDIN_FILENO) != STDIN_FILENO) err_sys("dup 2 error to stdin"); close(fd[0]); /* don't need this after dup 2 */ } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 14

Figure 15. 6: pipe more /* get arguments for execl() */ if ( (pager

Figure 15. 6: pipe more /* get arguments for execl() */ if ( (pager = getenv("PAGER")) == NULL) pager = DEF_PAGER; if ( (argv 0 = strrchr(pager, '/')) != NULL) argv 0++; /* step past rightmost slash */ else argv 0 = pager; /* no slash in pager */ if (execl(pager, argv 0, (char *) 0) < 0) err_sys("execl error for %s", pager); } } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 15

Figure 15. 6 n n n n Create a pipe Call fork Parent closes

Figure 15. 6 n n n n Create a pipe Call fork Parent closes read end Parent writes file to pipe Child closes write end Child calls dup 2 (stdin read end) Child execs pager (e. g. more) Pager reads from pipe (its stdin) Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 16

Using 2 pipes for parent/child synchronization Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National

Using 2 pipes for parent/child synchronization Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 17

Figure 15. 7: Pipe sync #include “apue. h" static int pfd 1[2], pfd 2[2];

Figure 15. 7: Pipe sync #include “apue. h" static int pfd 1[2], pfd 2[2]; void TELL_WAIT() { if (pipe(pfd 1) < 0 || pipe(pfd 2) < 0) err_sys("pipe error"); } void TELL_PARENT(pid_t pid) { if (write(pfd 2[1], "c", 1) != 1) err_sys("write error"); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 18

Figure 15. 7: Pipe sync void WAIT_PARENT(void) { char c; if (read(pfd 1[0], &c,

Figure 15. 7: Pipe sync void WAIT_PARENT(void) { char c; if (read(pfd 1[0], &c, 1) != 1) err_sys("read error"); if (c != 'p') err_quit("WAIT_PARENT: incorrect data"); } void TELL_CHILD(pid_t pid) { if (write(pfd 1[1], "p", 1) != 1) err_sys("write error"); } void WAIT_CHILD(void) { char c; if (read(pfd 2[0], &c, 1) != 1) err_sys("read error"); if (c != 'c') err_quit("WAIT_CHILD: incorrect data"); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 19

popen & pclose Functions n All dirty work: n n n create a pipe

popen & pclose Functions n All dirty work: n n n create a pipe fork a child close unused ends of pipe exec a shell to execute a command wait for command to terminate #include <stdio. h> FILE *popen(const char *cmdstring, const char *type); n Returns: file pointer if OK, NULL on error int pclose(FILE *fp); n Returns: termination status of cmdstring, or -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 20

popen: type = r or w type = r type = w Slides© 2008

popen: type = r or w type = r type = w Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 21

Figure 15. 11: pager (popen) #include <sys/wait. h> “apue. h" #define PAGER "${PAGER: -more}"

Figure 15. 11: pager (popen) #include <sys/wait. h> “apue. h" #define PAGER "${PAGER: -more}" /* env var, or default */ int main(int argc, char *argv[]) { char line[MAXLINE]; FILE *fpin, *fpout; if (argc != 2) err_quit("usage: a. out <pathname>"); if ( (fpin = fopen(argv[1], "r")) == NULL) err_sys("can't open %s", argv[1]); Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 22

Figure 15. 11: pager (popen) if ( (fpout = popen(PAGER, "w")) == NULL) err_sys("popen

Figure 15. 11: pager (popen) if ( (fpout = popen(PAGER, "w")) == NULL) err_sys("popen error"); /* copy argv[1] to pager */ while (fgets(line, MAXLINE, fpin) != NULL) { if (fputs(line, fpout) == EOF) err_sys("fputs error to pipe"); } if (ferror(fpin)) err_sys("fgets error"); if (pclose(fpout) == -1) err_sys("pclose error"); exit(0); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 23

Filter Program (with popen) Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng

Filter Program (with popen) Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 24

Figure 15. 14 (filter) #include <ctype. h> “apue. h" int main(void) { int c;

Figure 15. 14 (filter) #include <ctype. h> “apue. h" int main(void) { int c; while ( (c = getchar()) != EOF) { if (isupper(c)) c = tolower(c); if (putchar(c) == EOF) err_sys("output error"); if (c == 'n') fflush(stdout); } exit(0); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 25

Figure 15. 15 (using filter) #include <sys/wait. h> “apue. h" int main(void) { char

Figure 15. 15 (using filter) #include <sys/wait. h> “apue. h" int main(void) { char line[MAXLINE]; FILE *fpin; if ( (fpin = popen("myuclc", "r")) == NULL) err_sys("popen error"); } for ( ; ; ) { fputs("prompt> ", stdout); fflush(stdout); if (fgets(line, MAXLINE, fpin) == NULL) break; if (fputs(line, stdout) == EOF) err_sys("fputs error to pipe"); } if (pclose(fpin) == -1) err_sys("pclose error"); putchar('n'); exit(0); /* read from pipe */ Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 26

Coprocesses n Filter n n A program that reads from stdin and writes to

Coprocesses n Filter n n A program that reads from stdin and writes to stdout Coprocess n n A program that generates the filter’s input and reads the filter’s output Korn shell provides coprocesses More Information on Korn shell coprocess: http: //publib. boulder. ibm. com/infocenter/systems/index. jsp? topic=/com. ibm. aix. howtos/doc/howto/korn_shell_coprocess_facil. htm n Bourne, Bourne-again, C shells do not provide coprocesses Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 27

Driving a coprocess parent fd 1[1] fd 2[0] child (coprocess) pipe 1 pipe 2

Driving a coprocess parent fd 1[1] fd 2[0] child (coprocess) pipe 1 pipe 2 stdin stdout Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 28

Figure 15. 17 Simple filter to add 2 numbers Executable file name: add 2

Figure 15. 17 Simple filter to add 2 numbers Executable file name: add 2 #include "apue. h" int main(void) { int n, int 1, int 2; char line[MAXLINE]; while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) { line[n] = 0; /* null terminate */ if (sscanf(line, "%d%d", &int 1, &int 2) == 2) { sprintf(line, "%dn", int 1 + int 2); n = strlen(line); if (write(STDOUT_FILENO, line, n) != n) err_sys("write error"); } else { if (write(STDOUT_FILENO, "invalid argsn", 13) != 13) err_sys("write error"); } } exit(0); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 29

Figure 15. 18 Driver for add 2 filter (1/4) #include "apue. h" static void

Figure 15. 18 Driver for add 2 filter (1/4) #include "apue. h" static void sig_pipe(int); /* our signal handler */ int main(void) { int n, fd 1[2], fd 2[2]; pid_t pid; char line[MAXLINE]; if (signal(SIGPIPE, sig_pipe) == SIG_ERR) err_sys("signal error"); if (pipe(fd 1) < 0 || pipe(fd 2) < 0) err_sys("pipe error"); Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 30

Figure 15. 18 Driver for add 2 filter (2/4) if ((pid = fork()) <

Figure 15. 18 Driver for add 2 filter (2/4) if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid > 0) { /* parent */ close(fd 1[0]); close(fd 2[1]); while (fgets(line, MAXLINE, stdin) != NULL) { n = strlen(line); if (write(fd 1[1], line, n) != n) err_sys("write error to pipe"); if ((n = read(fd 2[0], line, MAXLINE)) < 0) err_sys("read error from pipe"); if (n == 0) { err_msg("child closed pipe"); break; } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 31

Figure 15. 18 Driver for add 2 filter (3/4) line[n] = 0; /* null

Figure 15. 18 Driver for add 2 filter (3/4) line[n] = 0; /* null terminate */ if (fputs(line, stdout) == EOF) err_sys("fputs error"); } if (ferror(stdin)) err_sys("fgets error on stdin"); exit(0); } else { /* child */ close(fd 1[1]); close(fd 2[0]); if (fd 1[0] != STDIN_FILENO) { if (dup 2(fd 1[0], STDIN_FILENO) != STDIN_FILENO) err_sys("dup 2 error to stdin"); close(fd 1[0]); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 32

Figure 15. 18 Driver for add 2 filter (4/4) if (fd 2[1] != STDOUT_FILENO)

Figure 15. 18 Driver for add 2 filter (4/4) if (fd 2[1] != STDOUT_FILENO) { if (dup 2(fd 2[1], STDOUT_FILENO) != STDOUT_FILENO) err_sys("dup 2 error to stdout"); close(fd 2[1]); } if (execl(". /add 2", "add 2", (char *)0) < 0) err_sys("execl error"); } exit(0); } static void sig_pipe(int signo) { printf("SIGPIPE caughtn"); exit(1); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 33

What if add 2 uses stdio? #include "apue. h“ int main(void) { int 1,

What if add 2 uses stdio? #include "apue. h“ int main(void) { int 1, int 2; char line[MAXLINE]; while (fgets(line, MAXLINE, stdin) != NULL) { if (sscanf(line, "%d%d", &int 1, &int 2) == 2) { if (printf("%dn", int 1 + int 2) == EOF) err_sys("printf error"); } else { if (printf("invalid argsn") == EOF) err_sys("printf error"); } } exit(0); } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 34

What if add 2 uses stdio? n Since stdin and stdout of add 2

What if add 2 uses stdio? n Since stdin and stdout of add 2 are both pipes n n Default buffering: fully buffered fgets() is blocked in add 2 Driver is blocked reading from pipe DEADLOCK!!! Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 35

Solution n Insert these 4 lines before while() if (setvbuf(stdin, NULL, _IOLBF, 0) !=

Solution n Insert these 4 lines before while() if (setvbuf(stdin, NULL, _IOLBF, 0) != 0) err_sys(“setvbuf error”); if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) err_sys(“setvbuf error”); n n Buffering changed to line buffered No deadlock!!! Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 36

FIFOs n n n n Also called “named pipes” Can be used by unrelated

FIFOs n n n n Also called “named pipes” Can be used by unrelated processes File type: stat. st_mode = FIFO Test with S_ISFIFO macro Similar to creating a file Pathname exists open, close, read, write, unlink, etc Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 37

FIFOs #include <sys/stat. h> int mkfifo (const char *pathname, mode_t mode); n Returns: 0

FIFOs #include <sys/stat. h> int mkfifo (const char *pathname, mode_t mode); n Returns: 0 if OK, -1 on error n mode: same as for open function Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 38

Uses of FIFOs n n Used by shell commands to pass data from one

Uses of FIFOs n n Used by shell commands to pass data from one shell pipeline to another, without creating intermediate temporary files Used as rendezvous points in clientserver applications to pass data between clients and servers Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 39

Using FIFOs to Duplicate Output Streams n n n Copies stdin to stdout and

Using FIFOs to Duplicate Output Streams n n n Copies stdin to stdout and file mkfifo 1 prog 3 < fifo 1 & prog 1 < infile | tee fifo 1 | prog 2 Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 40

Client-Server Communication Using a FIFO n n n Server creates a “well-known” FIFO to

Client-Server Communication Using a FIFO n n n Server creates a “well-known” FIFO to communicate with clients To avoid interleaving of client data, client must write at most PIPE_BUF bytes at a time Problem: Server can’t reply clients using a single “well-known” FIFO Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 41

Client-Server Communication Using a FIFO Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung

Client-Server Communication Using a FIFO Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 42

Client-Server Communication Using a FIFO n Solution: Create a FIFO for each client such

Client-Server Communication Using a FIFO n Solution: Create a FIFO for each client such that server can reply using the client-specific FIFO n n E. g. /tmp/serv 1. XXXXX, where XXXXX is client’s process ID Problems: n n Impossible for server to know if a client has crashed, FIFOs left in system, server must catch SIGPIPE (FIFO with 1 writer, no reader) Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 43

Client-Server Communication Using a FIFO Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung

Client-Server Communication Using a FIFO Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 44

XSI IPC n 3 IPC n n n Message Queues Semaphores Shared Memory u.

XSI IPC n 3 IPC n n n Message Queues Semaphores Shared Memory u. Originated in an internal AT&T version of UNIX called “Columbus UNIX” u. Later added to System V u. Criticized for inventing their own namespace instead of using the file system Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 45

XSI IPC n n Each IPC structure has a nonnegative integer identifier (large!) When

XSI IPC n n Each IPC structure has a nonnegative integer identifier (large!) When creating an IPC structure, a key must be specified n n n Type: key_t Defined in <sys/types. h> (long integer) Converted into an identifier by kernel Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 46

Client-Server Rendezvous at same IPC structure (1) n Server creates a new IPC structure

Client-Server Rendezvous at same IPC structure (1) n Server creates a new IPC structure using key = IPC_PRIVATE n n n Guarantees new IPC structure Server stores returned identifier in some file for client to obtain Disadvantage: file I/O! Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 47

Client-Server Rendezvous at same IPC structure (2) n n n Define a key in

Client-Server Rendezvous at same IPC structure (2) n n n Define a key in a common header Client and server agree to use that key Server creates a new IPC structure using that key Problem: key exists? (msgget, semget, shmget returns error) Solution: delete existing key, create a new one again! Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 48

Client-Server Rendezvous at same IPC structure (3) n Client and server agree on n

Client-Server Rendezvous at same IPC structure (3) n Client and server agree on n a pathname n a project ID (char between 0 ~ 255) n ftok() converts the 2 values into a key n Client and server use that key (cf. 2) n Disadvantage: ftok a function call! Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 49

Permission Structure for IPC struct ipc_perm { uid_t uid; /* owner’s EUID */ gid_t

Permission Structure for IPC struct ipc_perm { uid_t uid; /* owner’s EUID */ gid_t gid; /* owner’s EGID */ uid_t cuid; /* creator’s EUID */ gid_t cgid; /* creator’s EGID */ mode_t mode; /* access mode */ … }; Check <sys/ipc. h> on your system! Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 50

XSI IPC permissions Permission Bit User-read User-write (alter) 0400 0200 Group-read Group-write (alter) 0040

XSI IPC permissions Permission Bit User-read User-write (alter) 0400 0200 Group-read Group-write (alter) 0040 0020 Other-read Other-write (alter) 0004 0002 Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 51

Comparison of features Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University,

Comparison of features Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 52

Message Queues n n n n Linked list of messages Stored in kernel Identified

Message Queues n n n n Linked list of messages Stored in kernel Identified by message queue identifier msgget: create new or open existing q msgsnd: add new msg to a queue msgrcv: receive msg from a queue Fetching order: based on type Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 53

Message Queues n Message n n n Type: +ve long int Length: 0 Data

Message Queues n Message n n n Type: +ve long int Length: 0 Data bytes Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 54

Message Queues Each queue has a structure (Single UNIX Specification) struct msqid_ds { struct

Message Queues Each queue has a structure (Single UNIX Specification) struct msqid_ds { struct ipc_perm msg_perm; msgqnum_t msg_qnum; /* # msgs on queue */ msglen_t msg_qbytes; /* max # bytes on queue */ pid_t msg_lspid; /* pid of last msgsnd() */ pid_t msg_lrpid; /* pid of last msgrcv() */ time_t msg_stime; /* last-msgsnd() time */ time_t msg_rtime; /* last-msgrcv() time */ time_t msg_ctime; /* last-change time */ … }; n Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 55

System limits for message queues Description Typical values Free. BSD 5. 2. 1 Linux

System limits for message queues Description Typical values Free. BSD 5. 2. 1 Linux 2. 4. 22 Mac OS X 10. 3 Solaris 9 Size in bytes of largest message we can send 16, 384 8, 192 notsup 2, 048 The maximum size in bytes of a particular queue (i. e. , the sum of all the messages on the queue) 2, 048 16, 384 notsup 4, 096 The maximum number of message queues, systemwide 40 16 notsup 50 The maximum number of messages, systemwide 40 derived notsup 40 notsup = not supported Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 56

Message Queues #include <sys/msg. h> int msgget(key_t key, int flag); n n Returns: msg

Message Queues #include <sys/msg. h> int msgget(key_t key, int flag); n n Returns: msg queue ID if OK, -1 on error New queue is created or an existing queue is referenced Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 57

Operations on queue IPC_STAT: fetch into buf IPC_SET: set from buf IPC_RMID: remove queue

Operations on queue IPC_STAT: fetch into buf IPC_SET: set from buf IPC_RMID: remove queue from system #include <sys/msg. h> int msgctl(int msqid, int cmd, struct msqid_ds *buf); n Returns: 0 if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 58

Place data on message queue Pointer to: type + data (nbytes data) #include <sys/msg.

Place data on message queue Pointer to: type + data (nbytes data) #include <sys/msg. h> int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag); n Returns: 0 if OK, -1 on error Can specify IPC_NOWAIT Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 59

Message Structure struct mymesg { long mtype; /* +ve msg type */ char mtext[512];

Message Structure struct mymesg { long mtype; /* +ve msg type */ char mtext[512]; /* message data */ } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 60

Retrieve Message from Queue type == 0: 1 st msg type>0: 1 st msg

Retrieve Message from Queue type == 0: 1 st msg type>0: 1 st msg of type < 0: first msg with type <= |type| and smallest #include <sys/msg. h> int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag); n Returns: data size in message if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 61

Queues vs. Pipes vs. Sockets n Experimental Setup n n n Created IPC channel

Queues vs. Pipes vs. Sockets n Experimental Setup n n n Created IPC channel Called fork Parent Child: 200 MB of data n MQ: 100, 000 calls to msgsnd n n Message length=2000 bytes SP and UDS: 100, 000 calls to write n Length = 2000 bytes Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 62

MQ vs. SP vs. UDS Operation User System Clock Message queue 0. 57 3.

MQ vs. SP vs. UDS Operation User System Clock Message queue 0. 57 3. 63 4. 22 STREAMS pipe 0. 50 3. 21 3. 71 UNIX domain socket 0. 43 4. 45 5. 59 STREAMS pipes are faster than message queues! We shouldn’t use message queues in new applications! Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 63

Semaphores n n Need to be ATOMIC A counter to provide access to shared

Semaphores n n Need to be ATOMIC A counter to provide access to shared data object for multiple processes To obtain a shared resource: n n Test semaphore controlling resource If value > 0, value--, grant use If value == 0, sleep until value > 0 Release resource, value++, sleeping processes waiting for sem is awakened Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 64

XSI Semaphores n n n A semaphore is defined as a set of one

XSI Semaphores n n n A semaphore is defined as a set of one or more semaphore values Creation (semget) is independent of initialization (semctl) All IPCs exist even if no process is using them. n Need to worry about process terminating without releasing semaphore. Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 65

Semaphore structure struct semid_ds { struct ipc_perm sem_perm; unsigned short sem_nsems; /* #sems */

Semaphore structure struct semid_ds { struct ipc_perm sem_perm; unsigned short sem_nsems; /* #sems */ time_t sem_otime; /* last-semop() time */ time_t sem_ctime; /* last-change time */ … }; Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 66

Semaphore value structure struct { unsigned short semval; /* value >= 0 */ pid_t

Semaphore value structure struct { unsigned short semval; /* value >= 0 */ pid_t sempid; /* pid for last op */ unsigned short semncnt; /*#proc awaiting semval > curval*/ unsigned short semzcnt; /*#proc awaiting semval == 0 */ … }; Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 67

Obtain a semaphore Creating new set: nsems = #semaphores When referencing existing set: nsems

Obtain a semaphore Creating new set: nsems = #semaphores When referencing existing set: nsems = 0 #include <sys/sem. h> int semget (key_t key, int nsems, int flag); n Returns: sem ID if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 68

Semaphore operations n n n #include <sys/sem. h> int semctl (int semid, int semnum,

Semaphore operations n n n #include <sys/sem. h> int semctl (int semid, int semnum, int cmd, . . . /* union semun arg */); cmd: fetch semid_ds, set, remove sem, … Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 69

Comparison between semaphore v/s record locking n Allocate and release resources 100, 000 times

Comparison between semaphore v/s record locking n Allocate and release resources 100, 000 times by 3 processes Operation User System Clock Semaphores with undo 0. 38 0. 48 0. 86 Advisory record locking 0. 41 0. 95 1. 36 n n Record locking is slower! However, it is still preferred n Simpler, OS takes care of lingering locks when process terminates Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 70

Shared Memory n Fastest form of IPC n n no need of data copying

Shared Memory n Fastest form of IPC n n no need of data copying between client & server Must synchronize access to a shared memory segment n n Semaphores are used Record locking can also be used Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 71

Shared Memory Segment Structure struct shmid_ds { struct ipc_perm shm_perm; size_t shm_segsz; /* size

Shared Memory Segment Structure struct shmid_ds { struct ipc_perm shm_perm; size_t shm_segsz; /* size in #bytes */ pid_t shm_lpid; /* pid of last shmop */ pid_t shm_cpid; /* pid of creator */ shmatt_t shm_nattch; /* #current attaches */ time_t shm_atime; /* last-attach time */ time_t shm_dtime; /* last-detach time */ time_t shm_ctime; /* last-change time */ … }; Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 72

Obtain a shared memory id n n n #include <sys/shm. h> int shmget (key_t

Obtain a shared memory id n n n #include <sys/shm. h> int shmget (key_t key, int size, int flag); Returns: shared memory ID if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 73

Shared Memory Operations n n n #include <sys/shm. h> int shmctl (int shmid, int

Shared Memory Operations n n n #include <sys/shm. h> int shmctl (int shmid, int cmd, struct shmid_ds *buf); Returns: 0 if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 74

Attaching to a process addr=0 allow system to choose the first available address n

Attaching to a process addr=0 allow system to choose the first available address n n n #include <sys/shm. h> void *shmat (int shmid, void *addr, int flag); Returns: pointer to shared memory segment if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 75

Detaching from a process n n n #include <sys/shm. h> int shmdt (void *addr);

Detaching from a process n n n #include <sys/shm. h> int shmdt (void *addr); Returns: 0 if OK, -1 on error Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 76

Figure 15. 31: data storage #include <sys/shm. h> “apue. h" n #define ARRAY_SIZE MALLOC_SIZE

Figure 15. 31: data storage #include <sys/shm. h> “apue. h" n #define ARRAY_SIZE MALLOC_SIZE SHM_MODE n char n n n n n array[ARRAY_SIZE]; int main(void) { int char 40000 100000 0600 /* user read/write */ /* uninitialized data = bss */ shmid; *ptr, *shmptr; Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 77

Figure 15. 31: data storage n n n printf("array[] from %lx to %lxn", (unsigned

Figure 15. 31: data storage n n n printf("array[] from %lx to %lxn", (unsigned long)&array[0], (unsigned long)&array[ARRAY_SIZE]); printf("stack around %lxn", (unsigned long)&shmid); if ( (ptr = malloc(MALLOC_SIZE)) == NULL) err_sys("malloc error"); printf("malloced from %lx to %lxn", (unsigned long)ptr+MALLOC_SIZE); n if ( (shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0) err_sys("shmget error"); if ( (shmptr = shmat(shmid, 0, 0)) == (void *) -1) err_sys("shmat error"); printf("shared memory attached from %lx to %lxn", (unsigned long)shmptr+SHM_SIZE); if (shmctl(shmid, IPC_RMID, 0) < 0) err_sys("shmctl error"); n exit(0); n n n n } Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 78

Figure 15. 31: results n n n $. /a. out array[] from 804 a

Figure 15. 31: results n n n $. /a. out array[] from 804 a 080 to 8053 cc 0 stack around bffff 9 e 4 malloced from 8053 cc 8 to 806 c 368 shared memory attached from 40162000 to 4017 a 6 a 0 Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 79

Memory Layout (Figure 15. 31) 0 xbffff 9 e 4 0 x 4017 a

Memory Layout (Figure 15. 31) 0 xbffff 9 e 4 0 x 4017 a 6 a 0 0 x 40162000 0 x 0806 c 368 0 x 08053 cc 0 0 x 0804 a 080 Slides© 2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 80