* cormen book
[mascara-docs.git] / i86 / mtx-16-bit / mtx / notes4.html
blobc5d56425e57b92b75d56916f1aea9445ad871069
1 <Title>460 Notes</Title> <Body bgcolor="#00cccc" text="#000000"><H1>460 Notes #4</H1><Pre>
2 460 Notes #4 Process Management in Unix
4 1. Read Unix man pages on
5 fork, exec, wait, exit,
7 2. Processes:
8 A process is a sequence of executions regarded as a single entity for the
9 purpose of using system resources, such as CPU time, memory space,
10 opened files, I/O devices, etc. In general, a "resource" is anything that
11 may cause a process to wait.
13 When Unix starts, it creates a process P0 by brute-force. P0 uses the Unix
14 Kernel function to "fork" a child process P1, which in turn forks other
15 processes. From a user's point of view, the most important process is P1.
17 Unix's "fork" creates a child process idnetical to the parent (the caller of
18 fork). However, the child usually uses exec() to change its execution image
19 to a different file. So when P1 starts to run, it changes its image to
20 /etc/init. For this reason, P1 is also known as the "init" process.
22 While executing /etc/init, P1 reads a default configuration files, e.g.
23 /etc/inittab, to fork a child process on each terminal (or dial-in
24 line). Then P1 waits for ANY of the children processes to terminate.
26 When a process terminates, it wakes up the parent. When a "login process"
27 ends (by user logout), it wakes up P1, which usually "forks" another child
28 process on that terminal.
30 Each terminal process opens 3 FILEs; stdin, stdout, stderr, on its own
31 terminal. Then, it changes image to execute "/etc/getty" or /etc/login", in
32 which it displays a login: to its stdout and waits for user to login from
33 its stdin. When a user login, the terminal process gets the users uid and
34 gid (assigned to the user account in the /etc/passwd file), and becomes the
35 user's process.
37 The user's account also specifies which program the user will execute when
38 login, usually sh. So, the user process changes image to execute sh, which
39 prompts the user for input commands.
41 For each input command, sh forks a child to execute the command (file).
42 Meanwhile, sh waits for the child to terminate. When the child dies, it
43 wakes up the parent sh, which prompts for another command.
45 If the command line contains | or &, sh may fork several children processes,
46 all of which run concurrently.
48 If you have taken CS360 from me at WSU, you have written a C program that
49 simulates the Unix sh in a lab assignemnt. In case you did not or forgot,
50 please do the following.
51 ***********************************************************************
52 Use man to read the man pages of fork, exec, exit and wait
53 ***********************************************************************
54 3. Process Management in UNIX:
55 pid = fork() : creates a child process
56 exec() : change process image
57 exit(value) : terminate with a CODE=value
58 pid = wait(int *) : wait for a child to terminate, return its pid and
59 exit status
60 ==============================================================================
61 EXERCISES:
62 (DO THESE BUT NO NEED TO TURN IN)
64 Write C programs to demonstrate the use of Unix syscalls.
66 (1). forkSleep.c:
67 fork a child process.
68 Use getpid() and getppid() to identify each process.
69 Use sleep(SECONDS) to allow other processes to run first.
70 Before termination, print own pid and parent pid, and EXPLAIN
71 anything unusual you may have observed.
73 (2). forkWait.c:
74 fork a child. wait for the child to terminate. print its exit status.
75 Child process: terminate by exit(VALUE);
76 Parent : int status; pid = wait(&status);
77 print status in HEX to see its value.
78 (2). forkExec.c
79 fork a child process. Wait for the child to terminate.
80 print dead child pid and exit status.
82 Child process:
83 Use
84 execl("b.out", "b.out", "this", "is", "a", "test", 0);
85 to change image to execute a b.out file, passing as
86 parameters
87 "b.out", "this" "is" "a" "test"
88 In b.out, echo the parameters, which are argv[1],argv[2],.....
90 In b.out: (READ man on exec)
91 use execve() to change image again to c.out.
93 While in c.out,
94 print the parameters and the environmet variable strings.
96 ===============================================================================
97 4. Process Synchronization in Unix Kernel
99 The Unix kernel uses
100 sleep(int event);
101 and wakeup(int event);
102 for process synchronization.
104 (1). When a process must wait for something (called an event in Unix kernel)
105 it calls
106 sleep(event);
107 in which it records the event value in the proc structure, changes its
108 status to SLEEP, and gives up CPU. A sleeping process will not run until
109 it is awakened by another process or an interrupt handler through
110 wakeup(event).
112 (2). An event is anything a process may sleep on, as long as another process
113 will issue a wakeup(event) on that event value. In the Unix kernel, events
114 are usually (global) variable addresses in the Unix Kernel, whcih are
115 unique, so that processes may "sleep" on distinct event values, and
116 wakeup(event) only wakes up those processes that are sleeping on the
117 specified event value.
119 Examples:
120 wait for child process termination ==> sleep on its own &proc.
121 wait for an i/o buffer ===> sleep on that i/o buffer address.
123 (3). Many processes may sleep for the same event. (which is natural).
125 (4). When an event occurs, someone (a process or an interrupt handler) will
126 call wakeup(event), which wakes up ALL processes sleeping on that event.
127 If no process is sleeping on the event, wakeup() has no effect, i.e.
128 same as a NOP (No Operation).
130 NOTE: There is no record whether an event has occurred or not. In order NOT
131 to miss the wakeup(event) call, a process must go to sleep() BEFORE
132 the awaited event occurs. In a uniprocessor (Single CPU) system, this
133 is always achievable. However, in a Multiprocessor (multi-CPU) system,
134 this (sleep first and wakeup later) condition cannot be guaranteed since
135 processes can run in "parallel" in real-time. So, sleep/wakeup works
136 only for Uniprocessor systems. For multiprocessor systems, we need
137 to use other process synchronization mechanisms, e.g. semaphores, which
138 will be discussed later.
140 ==============================================================================
141 (4). Unix kernel assigns a fixed priority to a process when it goes to sleep.
142 The priority, which will be the process' scheduling priority when it
143 wakeup, is determined by the importance of the "resouces". Thus, a
144 newly awakened process may have a very high prioirty
146 (5). The assigned priority also classifies a sleeping process as
147 SOUND sleepers : those who will not be awakened by "signals"
148 LIGHT sleepers : those who will be awakened by signals.
150 Examples:
151 sleep() for disk I/O completion (interrupt) : SOUND.
152 sleep() for KBD inputs from user : LIGHT.
153 ==============================================================================
155 5. Process Management in MTX
156 We shall implement the following operations for process management in MTX:
158 (1). kfork:
159 pid = kfork() creates a child proc and returns the child's pid.
160 The child proc is READY (put in readyQueue). When sechduled to run, it
161 RESUMES to the body() function.
163 LATER, we shall implement a pid=ufork() operation IDENTICAL TO fork()
164 in UNIX.
166 (2). exit:
167 A running proc calls kexit(value) to die. The actions of kexit() are:
168 Mark itself a ZOMBIE;
169 Record an exit value in its PROC.exitValue.
170 Give away children (dead or alive) to P1. Make sure P1 does not die if
171 other procs still exist.
172 Issue wakeup(&parentPROC) to wake up its parent;
173 Call tswitch(); to give up CPU (for the last time).
175 NOTE that when a proc dies, its PROC is marked as ZOMBIE, contains an exit
176 value, but the PROC is NOT yet freed. It will be freed by the parent proc
177 via the wait() operation.
179 (3). Wait for a child proc to die:
180 A proc calls pid = wait(int *status); to wait for A (ANY) child to die,
181 where pid is the dead child's pid and status is the child's exit value.
183 int wait(status) int *status;
185 if (no child)
186 return -1 for ERROR;
187 while(1){
188 if (found a ZOMBIE child){
189 copy child's exitValue to *status;
190 free the ZOMBIE child PROC;
191 return dead child's pid;
193 sleep(running); // sleep at its own &PROC
197 (4). sleep(event)/wakeup(event)
199 A proc call sleep(event) to sleep on an event:
201 sleep(int event)
203 running->event = event; //Record event in PROC
204 running->status = SLEEP; // mark itself SLEEP
205 // For fairness, put running into a FIFO sleepList so that they will wakeup in order
206 tswitch(); // not in readyQueue anymore
210 A proc calls wakeup(event) to wake up ALL procs sleeping on event value:
212 wakeup(int event)
214 for every proc p SLEEPing on this event do{
215 // remove p from sleepList if you implement a sleepList
216 p->status = READY; // make it READY
217 enqueue(&readyQueue, p) // enter p into readyQueue (by pri)
220 =============================================================================