A program on disk is a lifeless thing: a bunch of instructions (and maybe some static data), just sitting there. The OS is what takes those bytes and gets them running. The result β a running program β is the most fundamental abstraction the OS provides: the process process The OS abstraction of a running program β its address space, registers (PC, stack pointer), and I/O state such as open files. defined in ch. 4 β open in glossary .
And you never run just one. A desktop runs a browser, mail, music, and a game at once; a typical system has tens or hundreds of processes seemingly running at the same time β and nobody ever asks βis a CPU free right now?β That convenience is the point:
The Crux: How To Provide The Illusion Of Many CPUs?
Although there are only a few physical CPUs available, how can the OS provide the illusion of a nearly-endless supply of them?The answer (as the peach dialogue hinted): run one process, stop it, run another β time sharing time sharing Sharing a resource by letting one entity use it for a while, then another β how the CPU illusion is built. defined in ch. 4 β open in glossary of the CPU. Users can run as many concurrent processes as they like; the cost is performance, since each runs slower when the CPU is shared.
Tip: Use time sharing (and space sharing)
Time sharing lets many entities share a resource by taking turns β the CPU, or a network link. Its counterpart is space sharing space sharing Dividing a resource among users in space rather than time (e.g., disk blocks belong to one file until deleted). defined in ch. 4 β open in glossary : divide the resource in space instead. Disk blocks are naturally space-shared β once a block belongs to a file, it isnβt given to another until the file is deleted.Doing this well takes two kinds of machinery:
- Mechanisms β low-level methods and protocols that implement a needed piece of functionality; the mechanism mechanism A low-level method or protocol implementing a needed piece of functionality β the "how" answer (vs. policy's "which"). defined in ch. 4 β open in glossary answers a how question. The star example: the context switch context switch The mechanism that stops one program and starts another on a CPU by saving and restoring register state. defined in ch. 4 β open in glossary , which lets the OS stop one program and start another on a given CPU. Every modern OS has one.
- Policies β algorithms for making decisions; a policy answers a which question. Given many runnable programs, which runs? The scheduling policy scheduler The OS component whose policy decides which ready process runs next, using history, workload knowledge, and metrics. defined in ch. 4 β open in glossary decides, using historical information (who ran most recently?), workload knowledge (what kinds of programs?), and performance metrics (optimizing interactivity, or throughput?).
Tip: Separate policy and mechanism
A classic design paradigm: keep the how (mechanism) apart from the which (policy). Then you can swap scheduling policies without rethinking the context switch underneath β a form of modularity that recurs all through OS design.4.1 The Abstraction: A Process
What is a process, precisely? At any instant, summarize it by taking inventory of the parts of the machine it touches β its machine state machine state What a program can read or update while running: its memory, its registers, and its open I/O resources. defined in ch. 4 β open in glossary : what the program can read or update while running.
A process, inventoried: its machine state is memory + registers + I/O state. Special registers matter most: the program counter says which instruction runs next; the stack and frame pointers manage the call stack.
Three components, then: memory β instructions and data live there, and the memory the process can address is its address space (met in chapter 2); registers β many instructions read or update them, and a few special ones are load-bearing: the program counter program counter The register holding the address of the instruction to execute next (a.k.a. instruction pointer, IP). defined in ch. 4 β open in glossary (PC, a.k.a. instruction pointer) plus the stack pointer and frame pointer that manage the stack stack Memory region for function parameters, local variables, and return addresses; allocated by the OS at process creation. defined in ch. 4 β open in glossary of parameters, locals, and return addresses; and persistent storage β I/O information such as the processβs currently open files.
4.2 Process API
Chapter 5 covers the real UNIX calls; first, what any OSβs process interface must include:
Create
Some way to make new processes. Typing a shell command or double-clicking an icon is asking the OS to create a process and run your program.
Destroy
Most processes exit on their own; for the runaway ones, an interface to kill them forcefully.
Wait
Pause until some process stops running β useful whenever one process depends on another finishing.
Miscellaneous control
Beyond kill and wait: suspend a process for a while, then resume it.
Status
Ask about a process: how long has it run? What state is it in?
4.3 Process Creation: A Little More Detail
How does a program become a process? Here is Figure 4.1, recreated β and below it, the same story as a step-through:
Figure 4.1: Loading β from program to process. Code and static data are read from the on-disk executable into the processβs address space.
1Load the code
The program sits on disk (or SSD) in an executable format. The OS reads its code into the address space of the new process. Early OSes did all loading eagerly, up front; modern OSes load lazily β pieces only when needed β using paging machinery covered in the memory chapters.
Two details worth keeping: loading can be eager (everything up front β
early OSes) or lazy (pieces on demand β modern OSes, via paging and
swapping, explained in the memory-virtualization chapters). And the
heap heap Memory region for explicitly requested dynamic allocations β malloc() and free() in C.
defined in ch. 4 β open in glossary
starts small: as the program calls malloc(),
the OS may get involved to grow it.
With code loaded, stack and heap ready, and I/O wired up, the OS performs
its final trick: jump to main() β handing the CPU to the newborn process.
How that handoff works without giving up control forever is the puzzle of
chapter 6.
Check yourself
1.What exactly is the difference between a program and a process?
2.Which three ingredients make up a process's machine state?
3."How does the OS stop one program and start another?" vs. "Which program should run next?" β what kind of question is each?
4.Modern OSes load a program lazily. What does that mean?
5.Predict from the step-through: just before the OS jumps to main(), which of these has already happened?