Operating systems function at lower levels of abstraction
Kernel operates in supervisor mode
init (process #1): system startup
Kernel concerns
Process: (essentially) running program
Conventions for file descriptors
cin in C++)cout)cerr)File descriptors are used for low-level operations (read/write array of bytes)
FILE* or C++ iostream are language-level objects that wrap a file descriptor
System call/trap
ints & pointersGlobal variable errno hold integer error code (raw info)
perror (standard library function) prints meaningful error messageUnix/Linux/Posix: separation between process creation & program invocation
pid_t pid = fork() clones process (not to be confused with Linux clone system call)
Child process inherits same open files as parents
Parent is responsible for collecting child exit status: wait/waitpid
Process tree
Fork is useful for distributing workload
But, what if you want to run a different program
Pipe: original IPC (inter-process communication) mechanism
Pipe is unidirectional: one end writes; other end reads
Pipe instance is a file descriptor (2 descriptors, one for write, other for read)
write/read system calls as regular file
vtbl)From programming POV (point-of-view), pipe is just like an ordinary file
pipe system call returns a pair of open file descriptors for producer (writer) & consumer (reader)
Single process can't really use pipe descriptors
File descriptor is index into a kernel data structure (array element)
Recall: files stay open across fork
Typically one process closes the reader and keeps the writer while the other does the opposite
Patterns of usage TODO: diagram
Shell syntax: vertical bar
do_this | do_thator operatorShell only supports pipelines with standard input/standard output
Basic file ops (read bytes, write bytes): good abstraction for many things
/dev/null, /dev/zero, /dev/randomStandard input (fd 0) & standard output (fd 1) are pre-opened by parent process
Standard input is not the keyboard; standard ouput is not the screen
Unless you have a good reason otherwise, your programs will be simpler & more flexible if you use standard input & standard output
Shell syntax for redirecting input/output
< standard input from file> standard output to file>> standard output append file2> standard error to file| pipe standard output of command 1 into standard input of command 2fork allows a program to divide work arcorss multiple processes, each running the same program
pipe is just one IPC mechanism
But what if you want to run a different program?
excve (plus several standard library wrappers that let you marshal arguments differently)exec* replaces current running program in process wtih new program, new argv
exec is successful, it does not return (you can't go home again)Open files (file descriptors) stay open across exec
Why separate calls for fork & exec?
fork, before execfork but not exec
exec without fork
init processWe now have enough information to construct a rudimentary shell
argv)stdin/stdout/stderrforkwait (or wait_pid)argvexecexit when doneTODO: diagram
TODO: diagram
Convex hull problem
Graham scan algorithm
Performance analysis:
TODO: diagrams
TODO: diagrams
Divide & conquer algorithm
The assignment is to use fork to compute the halves in separate processes
pipe)