130 likes | 301 Views
UNIX IPC. CSE 121 Spring 2003 Keith Marzullo. Creating a UNIX process. A process is created by making an exact copy of a running process. pid_t fork(void); Returns pid of child process to parent, 0 to child, -1 if error. The processes share the file pointer of each open file. A puzzle.
E N D
UNIX IPC CSE 121Spring 2003 Keith Marzullo
Creating a UNIX process A process is created by making an exact copy of a running process. pid_t fork(void); Returns pid of child process to parent, 0 to child, -1 if error. The processes share the file pointer of each open file. Review of Concurrency
A puzzle #include <sys/types.h> #include <unistd.h> int main (int argc, char **argv) { printf("Hello\n"); if (fork() == 0) printf("World.\n"); } Try running by itself versus redirecting its output (for example, to a file or via a pipe to cat). Why do the two executions produce different output? Ff you replace == with != , what happens? Review of Concurrency
Signals void (*signal (int sig, void (*disp)(int)))(int); Second parameter is either a handler or one of the two special values SIG_DFL and SIG_IGN. • Depending on the signal, SIG_DFL can cause an exit, an exit with a core, a stop, or can ignore. SIGINT 1 Exit ^C SIGSTP 23 Stop ^Z SIGQUIT 3 Core ^| SIGKILL 9 Kill (can not be caught) • Depending on the version of UNIX, handling a signal may re-install SIG_DFL. Review of Concurrency
Signals, II • A signal is raised when the process goes from being a kernel process to a user process. • A process in sleep can be interrupted, which can lead to the interruption of the originating system call. Review of Concurrency
Signals, III • A UNIX process produces a value (either directly returned from main or via exit system call. • When a process terminates, the value persists until collected by parent process. zombie process and the parent is sent a SIGCHLD. • SIG_DFL: ignore. • SIG_IGN: discard. • int wait(int *statusp) delays caller until signal received or one of its children processes terminates. • If using SIG_IGN, then will block until all children terminate, at which point wait fails. Review of Concurrency
Signals, IV int kill(pid_t pid, int sig); Sends signal sig to process pid. If pid> 0, then signal sent to process with pid. If pid< -1, then sent to process group -pid. If pid= 0, then then sent to process group of sender. If pid= -1, then will send to all processes (if sender is super-user) or to all processes whose real user ID is equal to the effective user ID of the sender. Review of Concurrency
Process groups pid_t setpgrp(void); 3 4 5 6 7 8 9 10 sets process group to the invoking process' id. pid_t setpgrp(void); returns the process group ID. Review of Concurrency
Pipes int mkfifo(const char *path,mode_t mode); creates a named pipe with name path and with permissions mode. • Accessed with read and write system calls (just like a file). • open blocks until there is a reader and a writer. • A read will return length zero after all consumed and readers have closed. • A write will raise SIGPIPE if all writers have closed. Review of Concurrency
Shared memory int shmget(key_t key, size_t size, int shmflg); • key_t can be IPC_PRIVATE • shmflg can be IPC_CREAT, IPC_EXCL plus low-bit mode flags. void *shmat(int shmid, const void *shmaddr, int shmflg); • shmflg can be SHM_RND, SHM_RDONLY. int shmdt(const void *shmaddr); int shmctl(int shmid, IPC_RMID); Review of Concurrency
Peterson’s Algorithm #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> struct shared {int in0, in1, turn; } *sm; int smid, loops; int main(int argc, char **argv) { smid = shmget(IPC_PRIVATE, sizeof(struct shared), IPC_CREAT | 0600); sm = shmat(smid, 0, 0); if (fork() == 0) { /* Process 0 */ for (loops = 0; loops < 10; loops++) { sm->in0 = 1; sm->turn = 1; while (sm->in1 && sm->turn == 1) ; sm->in0 = 0; } shmdt((void *) sm); } else { /* Process 1 */ for (loops = 0; loops < 10; loops++) { sm->in1 = 1; sm->turn = 0; while (sm->in0 && sm->turn == 0) ; sm->in1 = 0; } shmdt((void *) sm); shmctl(smid, IPC_RMID, NULL); } } Review of Concurrency
Semaphores int semget(key_t key, int nsems, int semflg); • key_t can be IPC_PRIVATE • semflg can be IPC_CREAT. int semop(int semid, struct sembuf *sops size_t nsops); • sops is an array of sembuf, each containing short sem_num short sem_op (>0, add; 0, allowed if semval is 0; <0, subtracted if will not make senval negative. short sem_flg (IPC_NOWAIT, SEM_UNDO) int semctl(int semid, 0, IPC_RMID, NULL); Review of Concurrency
P/V Mutex #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> static struct sembuf P = {0, -1, 0 }; static struct sembuf V = {0, 1, 0 }; int sem, loops; int main(int argc, char **argv) { sem = semget(IPC_PRIVATE, 1, 0600); semop(sem, &V, 1); if (fork() == 0) { /* Process 0 */ for (loops = 0; loops < 10; loops++) { semop(sem, &P, 1); semop(sem, &V, 1); } } else { /* Process 1 */ for (loops = 0; loops < 10; loops++) { semop(sem, &P, 1); semop(sem, &V, 1); } semctl(sem, 0, IPC_RMID, 0); } } Review of Concurrency