Download presentation
Presentation is loading. Please wait.
Published byAudra Greer Modified over 8 years ago
1
Textbook: Advanced Programming in the UNIX Environment, 2 nd Edition, W. Richard Stevens and Stephen A. Rago 1 Chapter 15. Interprocess Communication System Programming http://ecourse.elearning.ccu.edu.tw/ 熊博安 國立中正大學資訊工程學系 pahsiung@cs.ccu.edu.twpahsiung@cs.ccu.edu.twClass: EA-205 (05)2720411 ext. 33119Office: EA-512
2
Summary of UNIX System IPC IPC typeSUS FreeBSD 5.2.1 Linux 2.4.22 Mac OS X 10.3 Solaris 9 Half-duplex pipes FIFOs (full) (full) Full-duplex pipes Named full-duplex pipes Allowed XSI option, UDS UDS Opt, UDS UDS, UDS Message queues Semaphores Shared memory XSI Sockets STREAMS XSI option opt Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 2
3
3 Contents pipes FIFOs message queues semaphores shared memory
4
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 4 Pipes Oldest form of UNIX System IPC 2 Limitations of pipes: Historically, half-duplex (only 1-direction data flow) Modern OS, full-duplex (never assume this!) Must have a common ancestor (no names!) Still the most common form of IPC Shells use pipes between two processes
5
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 5 Pipes Process creates a pipe, forks, and uses the pipe to communicate with child #include int pipe (int fildes[2]); Returns: 0 if OK, -1 on error
6
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 6 Pipes Half-duplex pipes filedes[0]: open for reading filedes[1]: open for writing Output of filedes[1] is input of filedes[0] Full-duplex pipes filedes[0], filedes[1]: open for both reading and writing
7
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 7 Pipes
8
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 8 Half-duplex pipes after fork
9
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 9 Pipe (Parent Child)
10
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 10 Pipes Read from a pipe with write end closed: if data, data is read, and when no data, returns 0 ( EOF) Write to a pipe with read end closed: SIGPIPE generated, write() returns -1 with errno = EPIPE PIPE_BUF: #bytes in kernel ’ s pipe buffer size (no interleaving when write size PIPE_BUF)
11
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 11 Figure 15.5: Parent Child Pipe #include“apue.h" int main(void) { intn, fd[2]; pid_tpid; charline[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 world\n", 12); } else {/* child */ close(fd[1]); n = read(fd[0], line, MAXLINE); write(STDOUT_FILENO, line, n); } exit(0); }
12
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 12 Figure 15.6: pipe more #include #include“apue.h" #defineDEF_PAGER "/bin/more"/* default pager program */ int main(int argc, char *argv[]) { intn, fd[2]; pid_tpid; charline[MAXLINE], *pager, *argv0; FILE*fp; if (argc != 2) err_quit("usage: a.out ");
13
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 13 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"); }
14
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 14 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 (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) err_sys("dup2 error to stdin"); close(fd[0]);/* don't need this after dup2 */ }
15
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 15 Figure 15.6: pipe more /* get arguments for execl() */ if ( (pager = getenv("PAGER")) == NULL) pager = DEF_PAGER; if ( (argv0 = strrchr(pager, '/')) != NULL) argv0++;/* step past rightmost slash */ else argv0 = pager;/* no slash in pager */ if (execl(pager, argv0, (char *) 0) < 0) err_sys("execl error for %s", pager); }
16
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 16 Figure 15.6 Create a pipe Call fork Parent closes read end Parent writes file to pipe Child closes write end Child calls dup2 (stdin read end) Child execs pager (e.g. more) Pager reads from pipe (its stdin)
17
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 17 Using 2 pipes for parent/child synchronization
18
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 18 Figure 15.7: Pipe sync #include“apue.h" static intpfd1[2], pfd2[2]; void TELL_WAIT() { if (pipe(pfd1) < 0 || pipe(pfd2) < 0) err_sys("pipe error"); } void TELL_PARENT(pid_t pid) { if (write(pfd2[1], "c", 1) != 1) err_sys("write error"); }
19
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 19 Figure 15.7: Pipe sync void WAIT_PARENT(void) { charc; if (read(pfd1[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(pfd1[1], "p", 1) != 1) err_sys("write error"); } void WAIT_CHILD(void) { charc; if (read(pfd2[0], &c, 1) != 1) err_sys("read error"); if (c != 'c') err_quit("WAIT_CHILD: incorrect data"); }
20
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 20 popen & pclose Functions All dirty work: create a pipe fork a child close unused ends of pipe exec a shell to execute a command wait for command to terminate #include FILE *popen(const char *cmdstring, const char *type); Returns: file pointer if OK, NULL on error int pclose(FILE *fp); Returns: termination status of cmdstring, or -1 on error
21
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 21 popen: type = r or w type = r type = w
22
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 22 Figure 15.11: pager (popen) #include #include“apue.h" #define PAGER"${PAGER:-more}" /* env var, or default */ int main(int argc, char *argv[]) { charline[MAXLINE]; FILE*fpin, *fpout; if (argc != 2) err_quit("usage: a.out "); if ( (fpin = fopen(argv[1], "r")) == NULL) err_sys("can't open %s", argv[1]);
23
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 23 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); }
24
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 24 Filter Program (with popen)
25
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 25 Figure 15.14 (filter) #include #include“apue.h" int main(void) { intc; 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); }
26
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 26 Figure 15.15 (using filter) #include #include“apue.h" int main(void) { charline[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)/* read from pipe */ break; if (fputs(line, stdout) == EOF) err_sys("fputs error to pipe"); } if (pclose(fpin) == -1) err_sys("pclose error"); putchar('\n'); exit(0); }
27
Coprocesses Filter A program that reads from stdin and writes to stdout Coprocess A program that generates the filter’s input and reads the filter’s output Korn shell provides coprocesses Bourne, Bourne-again, C shells do not provide coprocesses Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 27 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
28
Driving a coprocess Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 28 fd1[1] fd2[0] stdin stdout pipe1 pipe2 parentchild (coprocess)
29
Figure 15.17 Simple filter to add 2 numbers #include "apue.h" int main(void) { intn, int1, int2; charline[MAXLINE]; while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) { line[n] = 0;/* null terminate */ if (sscanf(line, "%d%d", &int1, &int2) == 2) { sprintf(line, "%d\n", int1 + int2); n = strlen(line); if (write(STDOUT_FILENO, line, n) != n) err_sys("write error"); } else { if (write(STDOUT_FILENO, "invalid args\n", 13) != 13) err_sys("write error"); } exit(0); } Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 29 Executable file name: add2
30
Figure 15.18 Driver for add2 filter (1/4) #include "apue.h" static voidsig_pipe(int);/* our signal handler */ int main(void) { intn, fd1[2], fd2[2]; pid_tpid; charline[MAXLINE]; if (signal(SIGPIPE, sig_pipe) == SIG_ERR) err_sys("signal error"); if (pipe(fd1) < 0 || pipe(fd2) < 0) err_sys("pipe error"); Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 30
31
Figure 15.18 Driver for add2 filter (2/4) if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid > 0) { /* parent */ close(fd1[0]); close(fd2[1]); while (fgets(line, MAXLINE, stdin) != NULL) { n = strlen(line); if (write(fd1[1], line, n) != n) err_sys("write error to pipe"); if ((n = read(fd2[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
32
Figure 15.18 Driver for add2 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(fd1[1]); close(fd2[0]); if (fd1[0] != STDIN_FILENO) { if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO) err_sys("dup2 error to stdin"); close(fd1[0]); } Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 32
33
Figure 15.18 Driver for add2 filter (4/4) if (fd2[1] != STDOUT_FILENO) { if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO) err_sys("dup2 error to stdout"); close(fd2[1]); } if (execl("./add2", "add2", (char *)0) < 0) err_sys("execl error"); } exit(0); } static void sig_pipe(int signo) { printf("SIGPIPE caught\n"); exit(1); } Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 33
34
What if add2 uses stdio? #include "apue.h“ int main(void) { intint1, int2; charline[MAXLINE]; while (fgets(line, MAXLINE, stdin) != NULL) { if (sscanf(line, "%d%d", &int1, &int2) == 2) { if (printf("%d\n", int1 + int2) == EOF) err_sys("printf error"); } else { if (printf("invalid args\n") == EOF) err_sys("printf error"); } exit(0); } Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 34
35
What if add2 uses stdio? Since stdin and stdout of add2 are both pipes Default buffering: fully buffered fgets() is blocked in add2 Driver is blocked reading from pipe DEADLOCK!!! Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 35
36
Solution 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”); Buffering changed to line buffered No deadlock!!! Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 36
37
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 37 FIFOs 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
38
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 38 FIFOs #include int mkfifo (const char *pathname, mode_t mode); Returns: 0 if OK, -1 on error mode: same as for open function
39
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 39 Uses of FIFOs Used by shell commands to pass data from one shell pipeline to another, without creating intermediate temporary files Used as rendezvous points in client- server applications to pass data between clients and servers
40
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 40 Using FIFOs to Duplicate Output Streams mkfifo fifo1 prog3 < fifo1 & prog1 < infile | tee fifo1 | prog2 Copies stdin to stdout and file
41
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 41 Client-Server Communication Using a FIFO 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
42
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 42 Client-Server Communication Using a FIFO
43
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 43 Client-Server Communication Using a FIFO Solution: Create a FIFO for each client such that server can reply using the client-specific FIFO E.g. /tmp/serv1.XXXXX, where XXXXX is client ’ s process ID Problems: Impossible for server to know if a client has crashed, FIFOs left in system, server must catch SIGPIPE (FIFO with 1 writer, no reader)
44
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 44 Client-Server Communication Using a FIFO
45
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 45 XSI IPC 3 IPC Message Queues Semaphores Shared Memory Originated in an internal AT&T version of UNIX called “Columbus UNIX” Later added to System V Criticized for inventing their own namespace instead of using the file system
46
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 46 XSI IPC Each IPC structure has a nonnegative integer identifier (large!) When creating an IPC structure, a key must be specified Type: key_t Defined in (long integer) Converted into an identifier by kernel
47
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 47 Client-Server Rendezvous at same IPC structure (1) Server creates a new IPC structure using key = IPC_PRIVATE Guarantees new IPC structure Server stores returned identifier in some file for client to obtain Disadvantage: file I/O!
48
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 48 Client-Server Rendezvous at same IPC structure (2) 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!
49
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 49 Client-Server Rendezvous at same IPC structure (3) Client and server agree on a pathname a project ID (char between 0 ~ 255) ftok() converts the 2 values into a key Client and server use that key (cf. 2) Disadvantage: ftok a function call!
50
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 50 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 on your system!
51
XSI IPC permissions PermissionBit 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
52
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 52 Comparison of features
53
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 53 Message Queues 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
54
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 54 Message Queues Message Type: +ve long int Length: 0 Data bytes
55
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 55 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 */ … };
56
System limits for message queues DescriptionTypical values FreeBSD 5.2.1 Linux 2.4.22 Mac OS X 10.3 Solaris 9 Size in bytes of largest message we can send 16,3848,192notsup2,048 The maximum size in bytes of a particular queue (i.e., the sum of all the messages on the queue) 2,04816,384notsup4,096 The maximum number of message queues, systemwide 4016notsup50 The maximum number of messages, systemwide 40derivednotsup40 Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 56 notsup = not supported
57
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 57 Message Queues #include int msgget(key_t key, int flag); Returns: msg queue ID if OK, -1 on error New queue is created or an existing queue is referenced
58
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 58 Operations on queue #include int msgctl(int msqid, int cmd, struct msqid_ds *buf); Returns: 0 if OK, -1 on error IPC_STAT: fetch into buf IPC_SET: set from buf IPC_RMID: remove queue from system
59
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 59 Place data on message queue #include int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag); Returns: 0 if OK, -1 on error Pointer to: type + data (nbytes data) Can specify IPC_NOWAIT
60
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 60 Message Structure struct mymesg { long mtype; /* +ve msg type */ char mtext[512]; /* message data */ }
61
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 61 Retrieve Message from Queue #include int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag); Returns: data size in message if OK, -1 on error type == 0: 1st msg type>0: 1st msg of type type < 0: first msg with type <= |type| and smallest
62
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 62 Queues vs. Pipes vs. Sockets Experimental Setup Created IPC channel Called fork Parent Child: 200 MB of data MQ: 100,000 calls to msgsnd Message length=2000 bytes SP and UDS: 100,000 calls to write Length = 2000 bytes
63
MQ vs. SP vs. UDS OperationUserSystemClock Message queue0.573.634.22 STREAMS pipe0.503.213.71 UNIX domain socket0.434.455.59 Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 63
64
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 64 Semaphores A counter to provide access to shared data object for multiple processes To obtain a shared resource: 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 Need to be ATOMIC
65
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 65 XSI Semaphores 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. Need to worry about process terminating without releasing semaphore.
66
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 66 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 */ … };
67
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 67 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 */ … };
68
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 68 Obtain a semaphore #include int semget (key_t key, int nsems, int flag); Returns: sem ID if OK, -1 on error Creating new set: nsems = #semaphores When referencing existing set: nsems = 0
69
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 69 Semaphore operations #include int semctl (int semid, int semnum, int cmd,... /* union semun arg */); cmd: fetch semid_ds, set, remove sem, …
70
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 70 Comparison between semaphore v/s record locking Allocate and release resources 100,000 times by 3 processes Record locking is slower! However, it is still preferred Simpler, OS takes care of lingering locks when process terminates OperationUserSystemClock Semaphores with undo0.380.480.86 Advisory record locking0.410.951.36
71
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 71 Shared Memory Fastest form of IPC no need of data copying between client & server Must synchronize access to a shared memory segment Semaphores are used Record locking can also be used
72
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 72 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 */ … };
73
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 73 Obtain a shared memory id #include int shmget (key_t key, int size, int flag); Returns: shared memory ID if OK, -1 on error
74
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 74 Shared Memory Operations #include int shmctl (int shmid, int cmd, struct shmid_ds *buf); Returns: 0 if OK, -1 on error
75
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 75 Attaching to a process #include void *shmat (int shmid, void *addr, int flag); Returns: pointer to shared memory segment if OK, -1 on error addr=0 allow system to choose the first available address
76
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 76 Detaching from a process #include int shmdt (void *addr); Returns: 0 if OK, -1 on error
77
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 77 Figure 15.31: data storage #include #include“apue.h" #defineARRAY_SIZE 40000 #defineMALLOC_SIZE100000 #defineSHM_SIZE100000 #defineSHM_MODE0600/* user read/write */ chararray[ARRAY_SIZE];/* uninitialized data = bss */ int main(void) { intshmid; char*ptr, *shmptr;
78
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 78 Figure 15.31: data storage printf("array[] from %lx to %lx\n", (unsigned long)&array[0], (unsigned long)&array[ARRAY_SIZE]); printf("stack around %lx\n", (unsigned long)&shmid); if ( (ptr = malloc(MALLOC_SIZE)) == NULL) err_sys("malloc error"); printf("malloced from %lx to %lx\n", (unsigned long)ptr, (unsigned long)ptr+MALLOC_SIZE); 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 %lx\n", (unsigned long)shmptr, (unsigned long)shmptr+SHM_SIZE); if (shmctl(shmid, IPC_RMID, 0) < 0) err_sys("shmctl error"); exit(0); }
79
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 79 Figure 15.31: results $./a.out array[] from 804a080 to 8053cc0 stack around bffff9e4 malloced from 8053cc8 to 806c368 shared memory attached from 40162000 to 4017a6a0
80
Slides©2008 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 80 Memory Layout (Figure 15.31) 0xbffff9e4 0x4017a6a0 0x40162000 0x0806c368 0x08053cc8 0x08053cc0 0x0804a080
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.