Tues, Sept. 26
Back to Tanenbaum to
finish Chap 1.
UNIX
system calls—we looked
at write and exit earlier, now look at
fork(), the amazing parameterless UNIX
process-creation
system call.
Here
is a trivial fork
program, using the return value from fork to tell the parent and child
apart: The parent
gets the child pid
(always !=0) from fork, while the child gets back 0.
int
main()
{
if
(fork())
printf(“hello
from
parent\n”);
else
printf(“hello from child\n”);
}
When
you run this program,
you will see one message and then the other, in either order. Each terminates
by
executing the exit syscall
in the startup module.
After
fork, while both
processes exist, there is a parent-child relationship between them. If the parent exits first,
the child is an
orphan, and gets assigned to process 1 as a child.
Being an orphan doesn’t affect how it runs,
only how it gets cleaned up at the end.
Fork
clones the whole process
image, even the stack, so we can put in local variables and they will
be
copied:
int x_ext = 2; /* external var, in data
segment */
int main()
{
int x_loc=6;
/* local (automatic) var, on stack */
if (fork()) {
x_loc++;
x_ext++;
printf(“hello
from parent, x_loc=%d, x_ext =
%d\n”, x_loc, x_ext);
}
else
printf(“hello from child, x_loc=%d, x_ext = %d\n”, x_loc,
x_ext);
}
Here
x_loc, a local or automatic
variable, will be on the stack, = 6 in the original program image, and
thus =6
in the copied image as well. In
the
parent, x_loc will be incremented to 7, but this has no effect on the
child.
Similarly, x_ext is an external variable = 2 at the fork, so still 2 in the child’s report.
Question:
can UNIX processes
ever share memory?
Answer:
yes, via special
“shared memory” system calls, considered advanced
programming. The
memory involved would be in that big area
above the heap and below the stack, where the DLLs hang out.
Question:
fork() produces
another process, what about threads?
Answer:
threads share the
same process image, so thread programming is very
tricky—it’s easy for one
thread to damage data needed by another thread.
The processes are “bottled up” from
one another each in their own address
space.
Execve,
or exec for short,
replaces the current process image with one constructed from the
contents of an
executable file, i.e. it runs a program in the current process. A simple (UNIX) program
would be:
int main(int argc,
char *argv[])
{
int status;
if (fork()) {
waitpid(-1, &status, 0);
/* parent waits for child */
printf("status=%d\n",status);
} else {
/* run date in the child */
execve("/usr/bin/date", argv,
0);
/*
never get here, unless execve fails */
}
}
Here
we are passing argv
along from our old process to be the argv of the new image, since
execve wants
a non-trivial argv. Waitpid(-1,
...)
waits for any child to terminate, so the parent waits for date to run,
print
out the date, and exit, and then prints out “status =
0”, the success
status. Note that
the stdout, stdin, and
stderr fd’s pass live through the exec, so date has a good
stdout to use and we
see the output of date on the screen.
Stripped-down shell: look at code in Tan., pg. 49. Similar to above with loop
around it and
general command instead of just “date.”
We
have covered UNIX process
management system calls: fork, exec, waitpid, exit.
Win2K has no fork or exec system calls, only
the combination CreateProcess
system
call that takes the executable file as one of many parameters, and
creates a
new process running that program.
We
could write a “wshell”, something like the UNIX
shell with CreateProcess
instead of fork and exec, and WaitForSingleObject
(using the process handle returned by CreateProcess) after the
CreateProcess to
make the parent wait for termination of the program, itself done by ExitProcess.
NOTE:
Correction to Tan., pg.
50, Fig. 1-20: change FFFF to FFFFFFFF for a 32-bit address space.
Look
at the system call
conversion table, pg. 55:
Refs
on Win2k and UNIX/Win2K
porting issues: Microsoft Windows Internels, by
Russinovich and Solomon, also
MSDN knowledge base (www.msdn.microsoft.com,
and with MS Visual Studio). Also see WIndows System Programming, by Johnson Hart. This has UNIX vs Windows coverage too.
Def: OS provides virtual
machine for programs
UNIX
and Win2K have similar
virtual machine setups—
Also,
don’t forget 2 ways to
look at system call—function prototype, single instruction in
user program image.
Idea
of starting new job,
finding out they are using a special OS, say for embedded programming. What do you ask? Does it provide a flat
address space? timesharing?
automatic stack? (Windows 95
doesn’t), and what are the system calls?