Processes and System Calls

Learn how an operating system shares one CPU among many running programs and still keeps each program in its place. You will see what a process is and how it moves between running, ready and blocked; create processes in C with fork, run new programs with exec and collect their results with wait, up to a small shell with redirection and pipes. Then look under the hood: user mode and kernel mode, how a system call traps into the kernel, how exceptions and interrupts differ, and how limited direct execution and the timer interrupt let the OS take back the CPU and switch from one process to another.

IntermediateLesson 1 of 9 in Operating Systems Course

What you will learn

  1. Describe the operating system's main jobs and the history and design ideas that explain why it shares and protects the machine the way it does.
    • Describe the main jobs of an operating system
      Explain how the operating system turns raw hardware into easier, shared and protected resources for programs.
    • Explain how multiprogramming and time sharing shaped the OS
      Follow the steps from batch processing to multiprogramming and time sharing, see why each step needed new protections, and compare the main ways a kernel can be organized.
  2. Explain what a process is, what the operating system records about each one, and how processes move between running, ready and blocked.
    • Explain what a process is and what the OS keeps about it
      Distinguish a program from a process, describe a process's machine state and address space, and explain how the OS creates a process and keeps track of it.
    • Trace a process through its states
      Use the running, ready and blocked states and their transitions to trace how processes share one CPU, and recognize the extra states real systems report.
  3. Use the Unix process API in C to create child processes, run new programs in them, collect their results, end them and combine these calls into a simple shell.
    • Create a child process with fork
      Call fork, tell parent and child apart by its return value, and predict what each process sees and prints.
    • Run a different program with exec
      Replace the program in a process with exec, pass arguments correctly, and explain why Unix separates creating a process from loading a program.
    • Wait for children, read exit status and end processes
      End processes with exit and signals, collect a child's result with wait and waitpid, decode its status, and prevent zombies and orphans from causing trouble.
    • Build a simple shell with fork, exec, wait and redirection
      Combine the process calls into a shell loop that runs commands, redirects input and output, connects commands with pipes and runs jobs in the background.
  4. Explain how the hardware separates privileged kernel code from user programs, and how programs cross that boundary in a controlled way through system calls, exceptions and interrupts.
    • Distinguish user mode from kernel mode
      Explain what each CPU mode allows, which operations are privileged, and what happens when a program oversteps its mode.
    • Explain how a system call works, step by step
      Trace a system call from the library wrapper through the trap into the kernel and back, and interpret its return value and errors.
    • Tell traps, exceptions and interrupts apart
      Classify the events that move the CPU into the kernel, explain how the kernel's handler table works, and predict what happens after each kind of event.
  5. Explain how the operating system runs programs directly on the CPU at full speed while keeping control, and how it switches the CPU from one process to another.
    • Explain limited direct execution
      Explain the two problems of running programs directly on the CPU and how user mode, traps and the timer interrupt solve them, step by step from boot to process exit.
    • Trace a context switch and estimate its cost
      Follow each step of switching the CPU from one process to another, tell a context switch from a mode switch, and estimate how much CPU time switching costs.

Processes and System Calls study guide

5 chapters

1

Explain what an operating system does

The OS gives ordinary programs useful ways to compute, store data, and use devices while sharing the machine safely. Its responsibilities explain why a desktop application does not need its own disk driver and why one faulty program should not stop everything. Follow the move from one-job computers to interactive systems, then compare how different kernel designs divide privileged work.

1.1 Describe the main jobs of an operating system

A browser, a compiler, and a music player can all make progress on one computer. Each needs CPU time, memory, and access to devices. The operating system (OS) provides those resources through services that programs can use without controlling the whole machine.

Give programs useful resources

Virtualization turns a physical resource into a convenient virtual resource. CPU virtualization lets many processes behave as though each has its own processor. The OS runs each for a while and preserves its state between turns. Memory virtualization gives each process its own address space: the addresses its instructions can use.

An abstraction hides details behind a useful interface. A file is an abstraction for stored bytes. A program can call write without knowing whether those bytes go to an SSD or a network drive. A system call provides a controlled way to request a kernel service. Device-specific work stays behind the interface.

Share resources and protect programs

As a resource manager, the OS decides who gets CPU time, memory, and device service. It tries to keep hardware useful while giving programs reasonable access. Sharing also needs protection: one program must not overwrite another's private memory or disable the timer to keep the CPU.

The hardware helps enforce this boundary. Application instructions run in user mode with limited permissions. Kernel code runs with the privilege needed to manage the machine. A timer can interrupt a program even if that program never asks the OS for anything.

For a laptop downloading a file while compiling code, follow three separate jobs:

  1. The network device reports arriving data. The kernel makes it available to the downloading process.
  2. The OS shares CPU time between the browser, compiler, and other ready processes.
  3. The compiler requests file operations to store its output. Its code does not drive the storage controller directly.
Separate the kernel from the interface

The kernel is the privileged core. The shell, desktop, and most system libraries run as ordinary programs, even when they are distributed with the OS. Closing a desktop window does not remove the kernel. A server without a graphical interface still needs process management, memory protection, and device services.

On one logical CPU, user code and kernel code take turns. While the compiler executes ordinary user instructions, the kernel is not also executing on that CPU. System calls, exceptions, and hardware interrupts give it control again.

Choose how, then choose who

A mechanism supplies an operation; a policy chooses how to use it. Saving one process's registers and restoring another's is a mechanism. Choosing which ready process gets the next turn is policy. Keeping these separate lets the OS change its scheduling choices without replacing the switching machinery.

OS design balances useful abstractions, performance, protection, reliability, security, and energy use. The extra CPU time and memory spent on management are overhead. Across the subject, three recurring themes are virtualization, concurrency—activities in progress together—and persistence, which keeps stored data beyond a program's lifetime or loss of power.

Key Takeaways

  • Virtualization gives programs convenient views of shared hardware.
  • Abstractions such as files hide device details behind useful operations.
  • The kernel is privileged; the shell and desktop are ordinary programs.
  • Mechanism provides an operation; policy chooses when or for whom it is used.
  • Protection and low overhead are both goals of OS design.

1.2 Explain how multiprogramming and time sharing shaped the OS

Operating systems grew as computers moved from running isolated jobs to serving many activities at once. Each change solved a practical problem: idle hardware, slow interaction, or failures spreading between programs.

From batches to overlapping work

In batch processing, submitted jobs run one after another without interaction with the person who submitted them. Early support software mainly helped load jobs and perform common I/O operations. If the current job had to wait for a device, the CPU could sit idle.

Multiprogramming keeps several jobs in memory. When one blocks for I/O, another can compute. Suppose a job repeatedly computes for 20 ms and waits for disk I/O for 80 ms. Alone, its CPU utilization is 20 / 100 = 20%. With two such jobs and suitable overlap, useful computation can occupy 40% of the elapsed time. The device's delay has not become shorter; otherwise idle CPU time has been filled.

The gain depends on having work ready. Adding jobs cannot push CPU utilization above 100%, and jobs waiting for the same device can still face a bottleneck. Several jobs in memory also need protection: one must not overwrite another or damage the OS's own data.

Make interaction responsive

Time sharing gives processes short turns on the CPU. A terminal or desktop can respond while other programs continue working. Waiting for a batch job to finish before serving another user's keystroke would feel very different.

Sharing methodWhat is dividedExample
Time sharingUse of a resource across successive intervalsCPU turns
Space sharingCapacity held by different users at onceMemory regions or disk space

Concurrency means several activities are in progress during the same period. Their instructions can be interleaved on one logical CPU. Parallelism means instructions actually execute simultaneously on different processing resources. Multiprogramming does not require parallel hardware.

Put services inside or outside the kernel
DesignWhere most services runMain trade-off
Monolithic kernelFile systems, drivers, and networking run in kernel modeDirect calls are efficient; a driver bug can damage the kernel
MicrokernelA small privileged core supports user-mode service processesService isolation helps contain failures; communication adds work
Hybrid kernelCombines elements of both approachesThe exact service boundary depends on the design

Linux is monolithic and can load kernel modules. MINIX 3, QNX, and seL4 illustrate microkernel designs. Windows NT and Apple's XNU are commonly described as hybrid designs. A user-mode driver can often be restarted after a crash, while a privileged driver has access that can make its failure system-wide.

Early personal-computer systems such as MS-DOS and classic Mac OS lacked the process memory protection expected today. Modern systems combine OS rules with hardware enforcement. Short CPU turns alone would not stop a program from changing another program's memory; sharing and protection solve different parts of the problem.

Key Takeaways

  • Multiprogramming fills I/O waits with another job's computation.
  • Time sharing supports interactive use with short CPU turns.
  • Concurrent work can be interleaved on one CPU; parallel work executes simultaneously.
  • Time sharing divides turns; space sharing divides capacity.
  • Kernel organization trades direct service calls against stronger service isolation.
  • Multiple resident jobs require memory and privilege protection.
2

Describe processes and the states they move through

A program file is only the starting point. To run it, the OS builds and tracks an active process with memory, registers, open descriptors, and a place in the process list. Learn to read that state, then follow a pair of processes as CPU work overlaps with device waits. The difference between waiting for a CPU and waiting for an event explains which process the scheduler can choose.

2.1 Explain what a process is and what the OS keeps about it

An executable on disk can be launched repeatedly. Each launch needs its own changing state so that one instance can pause, resume, or fail independently. That active instance is a process.

Identify the running instance

A program is stored instructions and static data. A process combines a program with its current memory, CPU registers, and I/O state. Three shells can run the same executable while keeping different variables, current directories, and histories.

The program counter (PC) identifies the next instruction. The stack pointer locates the active stack. General registers hold intermediate values. When a process stops running, enough state must be preserved for it to continue at the right instruction with the right values.

Read the address-space picture

A process's address space is the memory its instructions can address. A common teaching layout places code and static data toward lower addresses, a heap above them, and a stack toward higher addresses. The heap supports dynamically allocated objects; the stack supports function calls and local state. In this layout, the heap grows toward higher addresses and the stack toward lower addresses. Actual layouts depend on the system, and malloc implementations can obtain memory in more than one way.

Two processes can print the same virtual address for a variable and still hold different values there. Virtual addresses belong to a process's view of memory. Matching address numbers do not establish shared writable storage.

Start a program

To start a new program image, the OS establishes these pieces:

  1. Its executable code and data, with parts loaded when needed on modern systems.
  2. An initial user stack and startup information, including the argument strings and argument vector used by the runtime to call main.
  3. Memory for dynamic allocation and the initial register state.
  4. An I/O environment, including inherited file descriptors.
  5. An entry point where program startup code begins.

On Unix, file descriptors are small integers naming open I/O resources. By shell convention, 0 is standard input, 1 standard output, and 2 standard error. They are often connected to a terminal. A process can inherit additional descriptors; the three familiar numbers are not a limit or a promise that every process always has them open.

Inspect the kernel's record

The process control block (PCB) records information the kernel needs to manage one process: PID, state, saved execution context, memory information, open descriptors, parent, owner, current directory, and accounting information. Linux uses task_struct; xv6 uses struct proc. A process table or process list organizes these records.

While a process runs, its live registers are in the CPU. On kernel entry, its user registers are saved on its kernel stack; a context switch also preserves the kernel execution context. The PCB is not a continuously updated mirror of every user register.

For example, a Linux ps listing might contain 8240 8200 S bash and 8291 8240 R ps. The second process has PID 8291 and parent PID 8240, so it is the shell's child. R covers both running and ready processes. A PID identifies a live process within its PID namespace, but after cleanup that number can be reused.

Key Takeaways

  • A process is a program instance with memory, register, and I/O state.
  • Identical virtual addresses in different processes can name different data.
  • The PCB holds the kernel's management record, not continuously live CPU registers.
  • File descriptors are inherited; 0, 1, and 2 have conventional roles.
  • PIDs can be reused after a process has ended and been cleaned up.

2.2 Trace a process through its states

A process can exist without executing an instruction right now. Its state tells the OS whether it can use a CPU or must first wait for something else. This distinction explains why a busy computer can have many processes but only a few executing at an instant.

Decide what the process needs
StateMeaningExample
RunningExecuting on a CPUA compiler generating instructions
ReadyAble to execute, waiting for CPU timeA computation whose turn just ended
BlockedWaiting for an event before it can continueA terminal read waiting for input

A blocked process consumes no CPU time while blocked. Its device or event can still make progress. A ready process already has what it needs except a CPU.

The basic transitions are ready → running when selected, running → ready when descheduled, running → blocked when it must wait, and blocked → ready when its event occurs. Event completion makes a process eligible; it does not grant it the CPU immediately. Choosing among eligible processes is the scheduler's job.

Trace overlapping work

Use one logical CPU and ignore switching overhead. Process A computes for 2 ms, waits for disk I/O for 3 ms, and then computes for 1 ms. Process B needs 4 ms of CPU time. A starts first.

IntervalCPUA's stateB's state
0–2 msARunningReady
2–5 msBBlockedRunning
5–6 msBReadyRunning
6–7 msARunningFinished

At 2 ms, A starts I/O and blocks. B computes while the disk works. At 5 ms, A's I/O finishes, but the OS lets B finish its fourth CPU millisecond before running A. This is a policy choice, not an extra state transition straight from blocked to running.

The total CPU work is 2 + 1 + 4 = 7 ms, and both finish after 7 ms. If A ran to completion before B began, elapsed time would be 2 + 3 + 1 + 4 = 10 ms. CPU utilization would be 7 / 10 = 70%, because no other work filled the I/O wait.

Read states on a real system

Linux ps combines running and ready as R. It shows interruptible sleep as S, uninterruptible sleep, often for I/O, as D, a stopped process as T, and a terminated but unreaped process as Z. A stopped process is not simply waiting for an ordinary I/O completion. A zombie has finished executing and retains only the record needed to report its result.

A new process also passes through creation before it is ready. On a system with four logical CPUs, at most four single-threaded processes can execute simultaneously. Ready queues organize eligible work; blocked lists track the events processes need. A context switch preserves one process's execution state and restores another's when the OS changes which process runs.

Key Takeaways

  • Ready means waiting for a CPU; blocked means waiting for an event.
  • An I/O completion moves a blocked process to ready.
  • Overlapping device waits with useful CPU work can shorten total elapsed time.
  • Linux reports ready and running with the same code, R.
  • A zombie is terminated but has not yet been reaped.
  • The number of logical CPUs limits simultaneous execution of single-threaded processes.
3

Create and control processes with fork, exec and wait

The Unix process interface separates creating a child, replacing its program, and collecting its result. Trace what each call changes and what it preserves, including private variables and shared open-file state. Then assemble the calls into shell behavior: foreground commands, redirection, pipelines, and background jobs. Each step depends on knowing which process is executing it.

3.1 Create a child process with fork

fork() creates a child process from the calling parent. Both continue immediately after the call, so one source-code path becomes two executions. Its return value tells each process which role it has.

Branch on all three results
pid_t rc = fork();
if (rc < 0) {
    perror("fork");
    exit(1);
} else if (rc == 0) {
    printf("child %ld\n", (long) getpid());
} else {
    printf("parent of %ld\n", (long) rc);
}

Use <unistd.h> for fork and getpid, <stdio.h> for printing, and <stdlib.h> for exit. On success, the parent receives the child's positive PID; the child receives 0. On failure, the caller receives -1, errno explains the error, and no child exists.

If the parent is PID 5000 and the child is 5001, the parent prints "parent of 5001" and the child prints "child 5001". Neither role is guaranteed to run first. getpid() returns the caller's own PID; getppid() returns its parent's PID. The child does not restart main or repeat instructions before the fork.

Follow private memory and shared I/O

Parent and child begin with matching ordinary memory contents in separate address spaces. If x is 10 before the call and the child sets its copy to 20, the parent's copy remains 10. Even the printed address of x can match: those equal virtual addresses belong to different process address spaces.

Copy-on-write avoids eagerly copying every memory page. Parent and child initially share physical pages with writes protected. When one writes a private page, the kernel arranges a private copy before allowing the write. This preserves the behavior of separate memory while reducing the cost of a child that soon calls exec.

File descriptors behave differently. Their copied entries refer to the same underlying open file description, which includes the current file offset. Sequential reads through an inherited descriptor advance that shared offset. The descriptor table is copied, but the kernel's underlying open-file state can remain shared.

Count only forks that a process reaches

With every call successful, fork(); fork(); leaves four processes: both processes produced by the first call execute the second. A three-iteration loop reached by all processes leaves 23=8 processes, including the original. A fork inside a parent-only branch is reached by fewer processes, so repeated doubling no longer describes the whole program.

Flush buffered text deliberately

printf can leave text in a user-space buffer. fork copies that buffer with the rest of memory. If output is redirected to a fully buffered stream, text printed before the fork can be flushed by both processes at normal exit.

For printf("start\n"); fork();, the usual line-buffered terminal flushes the newline before the fork. A redirected file may retain it and receive two copies. fflush(stdout) before fork() sends the pending text once. The duplicate comes from copied buffered data, not from executing the earlier printf twice.

Key Takeaways

  • fork() returns a child PID in the parent, 0 in the child, or -1 on failure.
  • Both successful paths continue just after fork().
  • Ordinary private memory changes in the child do not change the parent's values.
  • Inherited descriptors can share one open file description and offset.
  • Process counts depend on which processes reach each fork.
  • Flush pending output before a fork when duplicate flushing would be unwanted.

3.2 Run a different program with exec

A process can keep its identity while changing the program it runs. The exec family performs that replacement. Combining it with fork lets a parent continue its work while a child becomes a different program.

Replace the image, keep the process

Successful exec replaces the old code, static data, heap, and stack. The kernel prepares the new program's arguments and entry state, then begins its startup code. The old call site no longer exists, so successful exec never returns to it.

The PID, parent relationship, and current directory survive. Open descriptors survive except those marked close-on-exec. Caught signal dispositions reset to default; ignored dispositions generally stay ignored. Credentials usually remain the same, but an executable's set-user-ID or set-group-ID permissions can change effective credentials when permitted by the system.

OperationNew process?Main effect
fork()YesCreates a child with copied execution state
Successful execNoReplaces the calling process's program image
Build a valid argument vector

To run wc -l notes.txt, the child can use:

char *args[] = {"wc", "-l", "notes.txt", NULL};
execvp(args[0], args);
perror("execvp");
_exit(127);

The strings are separate arguments, not one combined command line. By convention, args[0] names the program. The final NULL is a pointer marking the end of the array; it is not the string "NULL". Without a valid terminator, the call can read beyond the array.

The lines after execvp handle failure. If the program cannot be found, exec returns -1 and sets errno, for example ENOENT. _exit then ends the child without flushing inherited C output buffers. Returning into the shell loop after failure would accidentally create another shell path.

Read the variant name

The v in execv means arguments arrive as a vector; l variants receive a list. A p variant searches PATH for a program name. An e variant supplies an explicit environment. Linux's underlying system call is execve; the library provides the convenient variants.

execvp("wc", args) searches PATH. execv("wc", args) treats "wc" as a relative pathname in the current directory. An absolute pathname such as /usr/bin/wc can be used where that executable is installed. Exec does not parse shell syntax: a > string in args is just an argument unless a program interprets it itself.

Use the interval before replacement

In the example with parent PID 6000 and child PID 6001, the child becomes wc but remains PID 6001. Its parent can wait for that PID. Before exec, the child can redirect descriptors, connect a pipe, or change directory; the replacement program inherits the prepared environment.

This separation is central to the Unix shell. Windows CreateProcess combines creation and program loading, using parameters to configure the new process. POSIX also offers posix_spawn for a combined operation.

Key Takeaways

  • Exec replaces a program image without creating a process or changing its PID.
  • On success exec never returns; following statements handle failure.
  • Terminate argument vectors with a NULL pointer.
  • p variants search PATH; a pathname-only variant does not.
  • Descriptor setup before exec lets an unchanged program participate in redirection and pipes.

3.3 Wait for children, read exit status and end processes

A parent needs to learn whether a child finished and how it ended. Process termination and result collection are separate steps: the child exits, then its parent reaps the kernel's remaining record.

End a process

Returning from main or calling exit(status) ends normal execution. exit flushes C output buffers and runs registered exit handlers. _exit(status) ends without that library cleanup, which is useful after a failed exec in a forked child. By convention, 0 means success and nonzero means failure.

A signal can also end a process. SIGTERM requests termination and can be handled; SIGKILL cannot be caught or ignored. SIGSTOP stops execution and also cannot be caught or ignored; SIGCONT resumes a stopped process. A terminal normally sends SIGINT for Ctrl-C and SIGTSTP for Ctrl-Z to the foreground job. A signal is a software notification to a process, not a hardware interrupt.

Wait for one result

wait(&status) waits for one child and returns its PID. waitpid(pid, &status, 0) selects a particular positive child PID. A finished, unreaped child can be collected immediately. Otherwise, an ordinary blocking wait suspends the parent until a matching result is available.

With WNOHANG, waitpid returns 0 when matching children exist but none has a result ready. A positive result identifies the collected child. A result of -1 is an error: ECHILD means no matching child remains; EINTR means a signal handler interrupted the wait.

Decode the status before using it
int status;
pid_t r;
do {
    r = waitpid(child, &status, 0);
} while (r == -1 && errno == EINTR);
if (r == -1) {
    perror("waitpid");
} else if (WIFEXITED(status)) {
    printf("exit %d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
    printf("signal %d\n", WTERMSIG(status));
}

This uses <sys/wait.h>, <errno.h>, and <stdio.h>. The stored status encodes the manner of termination as well as a result. WEXITSTATUS is meaningful after WIFEXITED succeeds; WTERMSIG follows WIFSIGNALED.

Only the low eight bits of a normal exit value are available. exit(300) therefore yields 44, while exit(-1) yields 255. On Linux, exit(3) commonly produces raw wait status 768; printing that raw integer is not decoding the exit code.

Reap zombies and recognize orphans

A zombie has terminated but retains its PID and result until a wait collects them. It executes no code, so sending SIGKILL cannot remove it. A long-running parent must reap each child. To collect all children, keep waiting after each positive PID, retry on EINTR, and stop on ECHILD; report other errors.

An orphan has lost its parent and can still run. Linux reparents it to an appropriate subreaper or the namespace's init process, which can collect its result later. Ordinary signal permissions depend on user identities and privileges. Running as root grants permissions, not kernel-mode execution.

Key Takeaways

  • Each successful wait collects one child's result.
  • Decode normal exit and signal termination with their matching status macros.
  • WNOHANG returns 0 when a matching child exists but has no result ready.
  • Retry an interrupted wait on EINTR; ECHILD means no matching child remains.
  • A zombie has ended; an orphan has lost its parent and may still be running.
  • SIGKILL and SIGSTOP cannot be caught or ignored.
  • exit flushes C buffers; _exit does not.

3.4 Build a simple shell with fork, exec, wait and redirection

A shell turns command text into process creation, descriptor setup, and result collection. It is an ordinary user program using the same protected OS services available to other programs.

Launch an external command

For wc -l notes.txt, the shell builds the argument vector and launches the command. The parsed words form a null-terminated argument vector, args:

pid_t child = fork();
if (child == -1) {
    perror("fork");
} else if (child == 0) {
    execvp(args[0], args);
    perror("execvp");
    _exit(127);
} else {
    int status;
    pid_t result;
    do {
        result = waitpid(child, &status, 0);
    } while (result == -1 && errno == EINTR);
    if (result == -1) perror("waitpid");
    else if (WIFEXITED(status)) {
        printf("exit %d\n", WEXITSTATUS(status));
    } else if (WIFSIGNALED(status)) {
        printf("signal %d\n", WTERMSIG(status));
    }
}

This uses <unistd.h>, <sys/wait.h>, <errno.h>, and <stdio.h>. The surrounding shell reads and parses each command, runs this launch path, then displays its next prompt.

Only the child replaces its program; the shell can collect a command crash as a termination result. Built-ins such as cd must change the shell's own state: changing a child's directory would leave the parent shell where it was.

Redirect a descriptor before exec

For ls -l > out.txt, the child opens the destination for writing, creating or truncating it. Then it makes standard output refer to that file:

int fd = open("out.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) { perror("open"); _exit(1); }
if (dup2(fd, STDOUT_FILENO) == -1) {
    perror("dup2"); _exit(1);
}
if (fd != STDOUT_FILENO && close(fd) == -1) {
    perror("close"); _exit(1);
}

open needs <fcntl.h>; descriptor calls and _exit use <unistd.h>. The creation mode is filtered by the process's file-creation mask. The fd != STDOUT_FILENO check keeps descriptor 1 open even if open itself returned 1. After successful setup, exec preserves descriptor 1 and ls writes normally without knowing about redirection.

An older approach closes descriptor 1 before opening the file: open returns the lowest unused descriptor. dup2 expresses the destination explicitly. Input redirection similarly connects a readable file to descriptor 0.

Connect two commands

For ls | wc -l, pipe(fds) creates a read end fds[0] and write end fds[1]. The producer child connects the write end to descriptor 1. The consumer child connects the read end to descriptor 0. After duplication, each closes the original pipe descriptors it does not need. The parent closes its copies and waits for both children.

Create both children before waiting for either. A producer can fill the pipe and block; the reader must exist to drain it. The reader reaches end-of-file only when all write descriptors are closed and buffered pipe data has been consumed. An unused write end held by the parent can keep wc waiting forever.

Keep the prompt available

For sleep 60 &, the shell launches the child and presents the next prompt without waiting immediately. It later uses nonblocking waits or responds to SIGCHLD to reap finished children.

Exit status also controls command combinations. make && ./app starts the second command only after success; make || echo failed starts the second only after failure. These decisions use the decoded result, not the raw encoded wait status.

Key Takeaways

  • An external command runs in a child; a state-changing built-in runs in the shell.
  • Redirection changes descriptors in the child before exec.
  • A pipe connects a producer's standard output to a consumer's standard input.
  • Launch both sides before waiting, and close unused pipe ends.
  • End-of-file requires every pipe write end to be closed after buffered data is consumed.
  • Background execution postpones waiting; the shell must still reap the child later.
4

Explain user mode, kernel mode and system calls

User programs need OS services without gaining control of the machine. Hardware privilege modes create that boundary, and controlled entry paths let the kernel act on requests and events. Trace a system call through its library wrapper and kernel handler, then distinguish deliberate traps, instruction faults, and device interrupts by their causes and possible outcomes.

4.1 Distinguish user mode from kernel mode

The kernel must let programs compute quickly while stopping operations that could take over the machine. The CPU's privilege mode is the hardware boundary that makes both possible.

Separate computation from privileged control

In user mode, instructions can access permitted process memory and perform ordinary computation. They cannot freely change the hardware configuration that protects other programs. In kernel mode, also called supervisor or privileged mode, the OS can perform the protected operations needed to manage the machine.

Privileged operations include programming the timer, disabling interrupts, installing interrupt handlers, changing memory-translation control registers, directly controlling protected devices, and halting the CPU. If any application could disable the timer, short CPU turns would depend on that application's cooperation.

PlatformApplication modeKernel mode
x86-64 on Linux or WindowsRing 3Ring 0
AArch64EL0EL1

AArch64 also provides EL2 for hypervisors and EL3 for secure firmware. These names identify hardware privilege levels, not different kinds of user accounts.

Enter at a controlled address

User code cannot raise its own privilege and choose any kernel address to execute. Entry happens through a system call, an instruction-caused exception, or a hardware interrupt. The CPU transfers control to an entry point configured by the OS. Kernel return code restores the saved user state and lowers the privilege level to resume application code.

The kernel also protects its data with memory permissions. A process may have kernel addresses in its virtual layout while still lacking user-mode permission to access them. Knowing an address does not grant access to the bytes there.

Consider an x86-64 Linux application executing hlt, an instruction intended to halt a CPU until an event. In user mode the instruction causes an exception. Linux normally sends SIGSEGV, whose default action terminates that process. The application does not halt the whole computer; the protection boundary turns the attempted privileged operation into an event the kernel handles.

Keep identity separate from mode

A root or administrator process is still a user-mode program while its own instructions run. Its user identity gives it broader permission to request services. It still enters the kernel through controlled paths, and the kernel checks the request.

For example, a privileged maintenance utility may be allowed to open a protected file. The utility asks through a system call; it does not become kernel code merely because the request is allowed. Conversely, when kernel code services an ordinary user's read, it executes in kernel mode even though the caller has no administrative identity.

On one logical CPU, this is a sequence: user instructions, kernel entry, kernel work, return to user instructions. It is not simultaneous execution of a program and a second OS task on that same CPU. Separate logical CPUs can execute different modes at the same instant.

Key Takeaways

  • User mode permits ordinary computation while restricting machine-control operations.
  • Kernel entry uses OS-configured entry points.
  • Root is a user identity; kernel mode is a CPU privilege state.
  • A forbidden user instruction raises an exception so the kernel can respond.

4.2 Explain how a system call works, step by step

A C program often appears to call an ordinary function when it needs an OS service. Underneath a system-call wrapper, a controlled CPU transition lets kernel code validate and carry out that request.

Distinguish a library call from a kernel request

The C library implements strlen in user space without a system call. printf formats data and may buffer it; a later write transfers bytes through the kernel. A thin read wrapper arranges arguments according to the platform's system-call convention and executes the entry instruction.

POSIX describes interfaces for Unix-like systems. Linux implements many services grouped broadly as process control, file and device operations, information, communication, and protection. A system-call number selects a service from the kernel's dispatch table. Numbers are platform-specific: Linux x86-64 uses 1 for write and 39 for getpid; AArch64 uses 64 for write.

Follow one write request

For write(1, "hi\n", 3) on Linux x86-64, follow the request in order:

  1. The wrapper places service number 1 in rax, descriptor 1 in rdi, the buffer address in rsi, and count 3 in rdx.
  2. syscall preserves the return address and flags in registers, enters kernel mode, and jumps to the configured entry point. It does not automatically switch stacks.
  3. Kernel entry code establishes the process's kernel stack and saves the remaining user state.
  4. Kernel dispatch selects write; the implementation checks the descriptor, user-buffer access, and the request before passing bytes toward the output resource.
  5. On a complete successful write, the result is 3 bytes. Kernel return code restores user state and resumes the wrapper, which returns to the caller.

Descriptor 1 may name a terminal, file, or pipe. The number alone does not identify the output device. A write can also return a smaller successful byte count; callers that must transfer every byte track the amount actually written.

Check errors at the interface

The kernel treats user pointers and other arguments as untrusted. A request to copy from an inaccessible buffer can fail with EFAULT; controlled copying avoids granting the caller access to kernel memory.

On Linux, a kernel error is a negative error code. The usual C wrapper reports -1 and sets errno. For example, if open("missing.txt", O_RDONLY) fails because the file does not exist, errno is ENOENT. perror("missing.txt") can display "missing.txt: No such file or directory". Inspect errno after a reported failure, not as the primary success test: a successful call need not clear an earlier error.

Account for time spent in the kernel

A call that can finish now may return to the same process. A blocking terminal read can instead put that process into the blocked state and let another run. The input event makes the reader ready; once scheduled, it completes the return path.

Kernel entry adds work beyond a normal function call: saving state, changing privilege, checking arguments, and restoring execution. Library buffering can combine small outputs into fewer writes. On Linux, strace ls runs ls while reporting its system calls, arguments, and results.

Key Takeaways

  • A library function can do all its work in user space or invoke system calls.
  • A service number selects a kernel operation; the caller does not choose an arbitrary kernel address.
  • Kernel code validates descriptors, pointers, and other arguments.
  • Use the return value to detect failure, then inspect errno.
  • A blocking system call can cause a context switch; kernel entry alone need not.
  • System-call numbers and register conventions depend on the OS and architecture.

4.3 Tell traps, exceptions and interrupts apart

Kernel entry can mean a service request, an instruction problem, or a device event. Classifying the cause helps you predict what the OS will do and whether the same instruction should run again.

Ask what caused the event
EventCauseTiming relative to the current instruction
System-call trapThe program deliberately requests a serviceSynchronous
Exception or faultThe current instruction needs special handlingSynchronous
Hardware interruptA timer or device signals the CPUAsynchronous

Synchronous means tied to the instruction being executed. It does not mean the same input causes exactly the same faults on every run. A load can fault when its page is absent and succeed later when that page is resident. Asynchronous means the event's cause is independent of the current instruction, such as a disk completing earlier work.

CPU manuals use these terms in different ways. Follow the cause: deliberate service request, instruction-caused event, or hardware notification.

Dispatch to the right handler

At boot, the OS installs protected handler addresses. A trap or interrupt table maps event kinds to kernel routines. On x86-64, the interrupt descriptor table (IDT) serves interrupts and exceptions; syscall uses an entry address in a special processor register. Only privileged code can configure these destinations.

On an interrupt from user mode, x86-64 hardware saves a return frame on a kernel stack. Entry code saves additional registers before doing the work. The syscall path preserves its initial return state in registers and relies on entry code to establish the kernel stack. Treating all entry paths as identical hardware actions hides an important implementation difference.

Choose the outcome

A valid page that is absent from memory can be loaded, after which the faulting instruction is retried. An access to memory the process may not use normally leads Linux to send SIGSEGV. An exception is therefore not always fatal, and it is not always a request to skip the current instruction.

For an actual x86-64 integer idiv instruction with divisor zero, the CPU raises a divide-error exception. Linux normally delivers SIGFPE; its familiar message mentions floating point even for this integer instruction. AArch64 integer divide instead gives zero for a zero divisor. C division by zero has undefined behavior, so portable C code cannot rely on either machine outcome.

When a disk read finishes, the interrupt handler records completion and makes the waiting process ready. That process may run later. A timer interrupt gives the OS a chance to reconsider the current CPU user, but the handler can also return to that same process.

Distinguish a signal from an interrupt

A hardware interrupt notifies the CPU; a signal notifies a process through the OS. An exception can cause the kernel to send a signal, and one process can request a signal for another through kill. Normal device completions are interrupts without implying program errors.

Kernel code must also protect shared data while events occur. It can disable interrupts briefly on a CPU and use locks where needed. Long interrupt-disabled periods delay device handling; disabling local interrupts alone does not prevent another CPU from accessing shared data.

Key Takeaways

  • Traps and exceptions arise from the current instruction; hardware interrupts have an external cause.
  • A recoverable fault can be repaired and its instruction retried.
  • Protected entry tables keep user programs from replacing kernel handlers.
  • A signal targets a process; a hardware interrupt targets CPU handling.
  • Device completion makes a blocked process ready, and a timer interrupt need not change processes.
5

Explain how the OS shares the CPU with limited direct execution

Fast execution and OS control have to work together. Limited direct execution lets ordinary instructions run on the hardware while modes, protected entry points, and a timer keep the kernel in charge. Follow what happens when the OS returns to the same process and when it resumes a different one. The saved state and switching costs explain how short CPU turns can support interactive work.

5.1 Explain limited direct execution

Running each application instruction in a software simulator would make CPU sharing expensive. Letting an application control the machine without limits would make sharing unsafe. Limited direct execution (LDE) uses ordinary hardware execution with a protected path back to the OS.

Solve two different control problems

Direct execution means a process's ordinary instructions execute on the CPU itself. The OS does not examine and approve every arithmetic instruction. Two problems remain: restricting operations that could damage the machine, and regaining control when a program does not voluntarily stop.

User mode solves the restriction problem. System-call traps let a program request services without choosing arbitrary privileged code. A hardware timer solves the control problem: it can interrupt an application that makes no calls at all. Together, these mechanisms support CPU virtualization at low overhead.

Prepare before applications run

At boot, the kernel configures event handlers and initializes the timer. These setup operations are privileged. Later user programs cannot redirect the handlers or disable the timer to avoid losing their turns.

To start a process, the OS creates its management record and memory image, prepares startup arguments and a user stack, and establishes initial register values. It arranges an initial saved context so the normal kernel-to-user return path can start the program. Conceptually, the process begins by returning from a trap it never made.

The detailed saved-frame layout depends on the CPU and OS. The useful design idea is reuse: the same restoration machinery can resume a suspended process or start a newly prepared one.

Return to the kernel voluntarily

During a system call, hardware preserves the initial return state and transfers control. Kernel entry code saves the additional registers on the process's kernel stack. After completing a nonblocking request, the kernel restores the process and returns to user mode. If the request blocks, another ready process can run first.

When main returns, runtime exit processing ultimately asks the kernel to terminate the process. Its memory can be freed while its termination record remains until a parent reaps it.

Return without cooperation

A cooperative system depends on programs making calls, yielding, or causing exceptions. An endless loop that does none of these can monopolize a CPU. Classic Mac OS illustrates this weakness.

A non-cooperative design uses a timer interrupt to force kernel entry. Consider a teaching model with one logical CPU and a periodic timer every 4 ms. The timer produces 1000 / 4 = 250 ticks per second. A user process stuck in while (1) { } is interrupted at the next tick. The kernel can then run a different ready process; the loop need not reach a system call first.

The tick is an opportunity to act, not a requirement to switch processes. The scheduler may let the interrupted process continue. Timer handling and saved-state restoration are mechanisms; the scheduler's choice is policy. Real response time also depends on kernel work and when interrupts can be handled, so a timer period by itself is not an application response-time guarantee.

Key Takeaways

  • LDE runs ordinary user instructions directly with hardware-enforced limits.
  • User mode restricts operations; system calls provide controlled privileged services.
  • A timer lets the OS regain control without cooperation from user code.
  • Boot-time setup protects handler addresses and timer configuration.
  • A timer tick gives the scheduler a choice; it does not require a process switch.

5.2 Trace a context switch and estimate its cost

Entering kernel mode does not necessarily change the running process. A context switch occurs when the kernel preserves one process's execution state and resumes another's. This requires both user-state preservation and a change in the kernel's own execution context.

Follow A out and B in

For a timer-driven switch on x86-64, trace the layers:

  1. A executes user instructions. The timer interrupts it.
  2. Hardware moves to kernel mode and saves A's interrupt return frame on A's kernel stack. Entry code saves A's other user registers there.
  3. The scheduler chooses B. The switch routine saves A's kernel execution context and restores B's saved kernel context, including its kernel stack pointer.
  4. The kernel changes to B's address-space context as needed. It is now running on B's behalf using B's kernel stack.
  5. Kernel exit code restores B's user registers. The return instruction restores B's return state and enters user mode. B resumes where it previously stopped.

The first save preserves A's interrupted user execution. The second preserves the kernel's place while handling A. They are not two identical full copies of the same register set. A PCB or associated context structure and the per-process kernel stack work together to preserve the state.

Identify the event and the decision

A blocking call, process exit, or a timer decision can lead to a switch. A device interrupt can make another process ready, and scheduling may then select it. All switching machinery runs in the kernel; an application does not save its own registers to volunteer for interruption.

SituationMode transition?Process change?
Nonblocking service returns to its callerUser → kernel → userNo
Timer handled, same process resumesUser → kernel → userNo
A blocks and B resumesKernel entry, then B's return pathYes

A context switch preserves the execution state needed to continue. Time passes and the outside world can change: shared file offsets and external inputs are not frozen while a process is paused.

Account for direct and indirect costs

Direct work includes running the scheduler, saving and restoring registers, and selecting an address space. Translation caches may need adjustment; tagged translations can avoid discarding all old entries. Indirect costs follow when B has to refill CPU caches or cached address translations displaced by A. The cost depends on hardware and workload, so use measured or stated values when calculating overhead.

Suppose a switch, including its relevant effects, costs 5 µs and useful CPU turns last 10 ms. Convert 10 ms to 10,000 µs. The switching share is 5 / (10,000 + 5), about 0.05%. For useful turns of 1 ms it is 5 / 1005, about 0.50%; at 0.1 ms it is 5 / 105, about 4.8%.

The denominator includes useful work plus switching time for one repeated cycle. A smaller turn can improve opportunities for interactive work but spends a larger fraction on repeated switching. The timer and switching code make short turns possible; scheduling policy must weigh that cost against responsiveness.

Key Takeaways

  • Kernel entry can return to the same process without a context switch.
  • User-state saving on entry and kernel-context saving during a switch serve different purposes.
  • Resuming B requires B's kernel stack, saved registers, and address-space context.
  • Switching costs include direct bookkeeping and later cache or translation refills.
  • Overhead share is switch cost divided by useful turn plus switch cost.
  • Shorter turns increase the switching share for a fixed per-switch cost.

Processes and System Calls examples

5 Walkthroughs

1

See what the OS contributes

12 steps
Follow shared resources from an application request to kernel services, then compare the designs that make shared use possible.
  1. 1
    IntroductionStart with several programs

    Imagine a laptop compiling a project while playing music and receiving network data. Each application needs CPU time, memory, and I/O, yet none controls the whole machine.

    Follow who supplies those resources, how several jobs make progress, and where the privileged services run. The recurring question is concrete: what work does the application request, and what work must the OS manage?

  2. 2
    ExplanationHide the device details

    The OS offers abstractions: useful interfaces that hide lower-level machinery. A program opens a file and reads bytes without implementing commands for every storage device.

    A system call requests a kernel service through a controlled interface. The kernel checks and performs the protected work. The application still decides which data it wants; it does not gain permission to drive the device directly.

  3. 3
    ExampleTrace a compiler output file

    A compiler produces bytes for an executable and requests a write. The kernel checks the output resource and handles the storage work behind the file interface.

    At the same time, the OS manages the compiler's memory and shares CPU time with the music player. One action—saving a file—therefore sits within several OS responsibilities: abstraction, resource management, and protection of the other programs.

  4. 4
    Key InsightGive each process a usable machine

    Virtualization presents a physical resource through a useful private view. A process can make progress as though it has a processor of its own, even though its instructions take turns with other processes.

    Its memory view is also private: the address it uses need not identify the same physical bytes in another process. CPU and memory virtualization give programs convenient models while the OS manages the actual shared hardware.

  5. 5
    ChallengeLocate the privileged part

    A computer has no graphical desktop installed, but it runs services, stores files, and shares CPU time. Has it lost the essential OS core? Explain.

    ---reveal---

    No. The kernel still manages processes, memory, and device services. A graphical desktop is a user program on top of those services. Its absence changes the interface a person sees, not the need for the kernel's resource-management work.

  6. 6
    ExplanationSeparate the operation from the choice

    A mechanism makes an action possible. Saving one process's registers and restoring another's provides the machinery for switching.

    A policy chooses how to use it, such as deciding which ready process gets the next CPU turn. The distinction matters when a design changes: a new choice rule can reuse the same reliable switching code. Efficient mechanisms alone do not decide what is fair.

  7. 7
    ExplanationFill an otherwise idle wait

    A batch system can leave the CPU idle while its current job waits for I/O. Multiprogramming keeps other jobs available and runs one during that wait.

    The waiting job does not compute and the device has not become faster. The gain comes from overlapping independent work: one process waits while another uses the CPU. Several resident programs also require protection so one cannot overwrite another's memory.

  8. 8
    ExampleCalculate the utilization gain

    A job computes for 20 ms, then waits for I/O for 80 ms. Alone, one 100 ms cycle contains only 20 ms of CPU work: utilization is 20%.

    With a second such job and suitable overlap, another 20 ms of computation can fill otherwise idle time, giving up to 40% in this illustration. The improvement uses waiting time productively; adding jobs cannot raise CPU utilization beyond 100%.

  9. 9
    ConnectionGive interactive work short turns

    Time sharing gives processes short CPU turns so interactive work need not wait for a whole batch job. This is concurrency even on one logical CPU: several activities progress through interleaving.

    Parallelism needs actual simultaneous execution on separate processing resources. Memory and disk capacity illustrate a different division, space sharing, in which different users hold separate portions at once.

  10. 10
    ExplanationChoose a service boundary

    A monolithic kernel, such as Linux, runs most services together with privilege. Direct calls are efficient, but a faulty driver can damage kernel state.

    A microkernel, such as seL4, leaves more services in separate user processes. Isolation can contain a service failure, at the cost of communication and mode transitions. Windows NT and XNU mix approaches. The boundary determines which failures can spread and which services can be restarted.

  11. 11
    ChallengeConnect sharing and protection

    A one-CPU system runs several jobs and switches to another whenever one waits for disk I/O. A proposal would let every job overwrite any memory address. Explain the utilization benefit and the flaw in this proposal.

    ---reveal---

    Multiprogramming fills I/O waits with another job's computation. Unrestricted writes would let one job damage another or the OS. Overlapping work improves resource use, but shared use still needs enforced memory and privilege protection.

  12. 12
    RecapRead a design in three questions

    For an OS design, ask which resource is shared, what interface a program sees, and what boundary protects other work.

    These questions connect CPU virtualization to process turns, files to hidden device details, and kernel organization to failure isolation. Mechanisms carry out protected operations; policies decide how to distribute their use. Concurrency can come from interleaving on one CPU.

2

Follow a process through CPU and I/O work

13 steps
Read a process record, then build a timeline that separates executing, waiting for a CPU, and waiting for an event.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionFollow an active instance
  2. 2
    ExplanationTurn a file into a process
  3. 3
    ExplanationPreserve the next instruction
  4. 4
    ExampleRead a process listing
  5. 5
    ChallengeInterpret equal addresses
  6. 6
    TipRead descriptors as inherited resources
  7. 7
    ExplanationAsk what is missing
  8. 8
    ExampleStart the timeline
  9. 9
    ExampleFinish the timeline
  10. 10
    ChallengeChange the ready-process decision
  11. 11
    ConnectionRecognize real state names
  12. 12
    ChallengeConnect records to CPU capacity
  13. 13
    RecapRead state as eligibility
3

Build a command from process calls

23 steps
Trace a child from fork through program replacement, result collection, redirection, and a connected pipeline.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionGive each call one job
  2. 2
    ExplanationSplit one execution into two
  3. 3
    ExampleFollow a private value
  4. 4
    ExampleCount a branch, not source calls
  5. 5
    ChallengeCount the printing paths
  6. 6
    TipCheck what was copied
  7. 7
    ExplanationReplace the child's program
  8. 8
    ExamplePass separate argument strings
  9. 9
    ChallengePredict a successful replacement
  10. 10
    Key InsightUse the gap before exec
  11. 11
    ExplanationCollect one child result
  12. 12
    ExampleDecode normal exit
  13. 13
    ExplanationLeave no uncollected results
  14. 14
    ChallengeHandle interruption correctly
  15. 15
    TipChoose a termination request
  16. 16
    ExplanationReturn to a foreground prompt
  17. 17
    ExampleRedirect output before replacement
  18. 18
    ChallengePreserve the output destination
  19. 19
    ExampleConnect the two pipe ends
  20. 20
    Key InsightLaunch before waiting
  21. 21
    ConnectionKeep background work accounted for
  22. 22
    ChallengeTrace an empty pipeline
  23. 23
    RecapTrack identity, image, and result
4

Trace a request across the privilege boundary

15 steps
Follow a service request into the kernel, then compare it with instruction faults and external device events.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionAsk why the kernel was entered
  2. 2
    ExplanationLimit what applications can control
  3. 3
    ExampleSeparate identity from privilege
  4. 4
    ChallengePredict a forbidden instruction
  5. 5
    ExplanationFind the actual system call
  6. 6
    ExamplePrepare one write
  7. 7
    ExampleEnter and validate
  8. 8
    ExampleInterpret the return
  9. 9
    ChallengeFollow a blocked read
  10. 10
    ExplanationClassify by the cause
  11. 11
    ExampleRepair or terminate
  12. 12
    TipKeep signals at the process layer
  13. 13
    ChallengeClassify a device completion
  14. 14
    ChallengeSeparate two kinds of entry
  15. 15
    RecapTrace cause, checks, and outcome
5

Keep control while programs execute directly

15 steps
Follow timer-driven control into a switch between processes, then estimate the fraction of time that switching consumes.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionKeep speed and control together
  2. 2
    ExplanationSolve two control problems
  3. 3
    ExamplePrepare the machine and process
  4. 4
    ConnectionSee the cooperative weakness
  5. 5
    ExampleInterrupt an endless loop
  6. 6
    ChallengeIdentify the missing mechanism
  7. 7
    ExplanationSave the interrupted user path
  8. 8
    ExampleSave the kernel path too
  9. 9
    ExampleReturn through B's saved state
  10. 10
    ChallengeSpot a mode-only transition
  11. 11
    ExplanationCount the costs after a switch
  12. 12
    ExampleBuild the full cycle denominator
  13. 13
    ChallengeEstimate a changed turn length
  14. 14
    ChallengeConnect a blocked call to resumption
  15. 15
    RecapFollow who owns the return path

Processes and System Calls practice questions

50 Practice Questions in 5 sets

Set 1: Resources, processes, and protection10 Practice Questions

Question 1 of 10

A program writes a file without knowing whether its data goes to an SSD or a network drive. What OS idea makes this possible?
  1. Time sharing of the storage device
  2. An abstraction for file operations
  3. Parallel execution of device requests
  4. A scheduling policy for the program
Show answerHide answer
Answer: B
A file interface hides the device-specific work behind operations the program can request. This is an abstraction: the program deals with bytes and files while the OS handles the device details. Time sharing concerns when a resource is used, not the interface that hides those details.

Question 2 of 10

An OS changes which ready process receives the next turn but keeps its register-saving routine unchanged. What changed?
  1. The address-space layout
  2. The privilege mechanism
  3. The register format
  4. The scheduling policy
Show answerHide answer
Answer: D
The selection rule is policy; the unchanged save-and-restore routine is mechanism. One switching mechanism can support several ways of choosing the next process. Changing the order of CPU turns does not by itself change how the machine preserves register state.

Question 3 of 10

A job repeatedly computes for 15 ms and then waits for I/O for 45 ms. What CPU utilization does it achieve when it is the only job and switching overhead is ignored?
  1. 25%
  2. 33.3%
  3. 75%
  4. 15%
Show answerHide answer
Answer: A
Each cycle lasts 15 + 45 = 60 ms, and only 15 ms contains computation. CPU utilization is therefore 15 / 60 = 25%. Dividing 15 by the 45 ms wait gives 33.3%, but utilization uses the whole elapsed cycle, including both computation and waiting.

Question 4 of 10

Two programs repeatedly take turns on one logical CPU before either finishes. How is their execution described?
  1. Parallel, with simultaneous execution
  2. Sequential, with each finishing first
  3. Concurrent, with interleaved execution
  4. Space-shared, with permanent CPU division
Show answerHide answer
Answer: C
Both activities are in progress over the same interval, so their execution is concurrent. A single logical CPU interleaves their instructions. Parallel execution would require simultaneous processing resources; rapidly switching turns does not make the instructions execute at the same instant.

Question 5 of 10

A process listing shows PID 9641, PPID 9600, and command name "sort". What process is its parent?
  1. The process whose PID is 9600
  2. The process whose PID is 9641
  3. Every process named "sort"
  4. The process created after 9641
Show answerHide answer
Answer: A
PPID names the parent process, so the parent has PID 9600. PID 9641 identifies the sort process itself. A command name can be shared by many process instances and does not replace the numeric parent relationship recorded by the kernel.

Question 6 of 10

Two separately launched copies of a program print the same virtual address for a private variable. One changes its value. What follows for the other copy?
  1. It sees the same write because the virtual addresses match.
  2. It sees the write only after both processes next enter the kernel.
  3. It keeps its value only until its next saved context is restored.
  4. It keeps its value because its address space is separate.
Show answerHide answer
Answer: D
Each process has its own private address space, so equal virtual address numbers can name different data. A write to one private variable does not update the other process's variable. Matching printed addresses alone do not establish a shared writable memory mapping.

Question 7 of 10

A process can continue computing but the timer has ended its CPU turn. What is its basic state now?
  1. Blocked, waiting for a timer completion
  2. Ready, waiting for another CPU turn
  3. Stopped, waiting for a resume signal
  4. Zombie, waiting for its parent to collect it
Show answerHide answer
Answer: B
The process has work available and needs only a CPU, so it is ready. Losing a turn does not make it blocked, because no I/O or other required event is preventing progress. Stopped and zombie states describe different situations: suspended execution and completed execution awaiting collection.

Question 8 of 10

On one logical CPU, M is running while N is blocked for a read. The device finishes N's read, and the kernel returns to M. What are the two basic states immediately afterward?
  1. M ready; N running
  2. M running; N blocked
  3. M running; N ready
  4. M blocked; N ready
Show answerHide answer
Answer: C
The completed read removes N's reason for blocking, so N becomes ready. M continues running because the kernel returned to it. Device completion makes N eligible but does not require the scheduler to give N the CPU immediately; treating completion as an automatic switch skips that decision.

Question 9 of 10

A maintenance utility runs with root identity and requests a protected file operation. In what mode do its own application instructions execute?
  1. Kernel mode, because root bypasses entry checks
  2. Supervisor mode until the file is closed
  3. User mode only when the requested file is public
  4. User mode, with permissions checked by the kernel
Show answerHide answer
Answer: D
Root is an identity with broader service permissions, not a CPU execution mode. The utility's application instructions still run in user mode and cross a controlled entry path for kernel work. Permission to open a protected file does not turn the utility itself into kernel code.

Question 10 of 10

A new OS enforces user-mode restrictions and protected system-call entry, but regains the CPU only when a program makes a call or faults. A user program enters an endless arithmetic loop. Why can this design fail to share one CPU?
  1. The loop can avoid every configured path back to the OS.
  2. The loop yields automatically whenever its next branch is taken.
  3. The kernel runs beside the loop on the same logical CPU.
  4. User-mode protection forces a ready-process choice after each instruction.
Show answerHide answer
Answer: A
The program can keep executing permitted instructions without making a call or causing an exception. The OS then has no independent event that forces entry so it can run another process. Privilege restrictions protect operations, but a timer interrupt is needed to regain control without cooperation.
Set 2: Create, replace, and collect a process10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

A parent receives 7421 from a successful fork. What value does that same fork return in the child?
  1. 7421
  2. -1
  3. 0
  4. The parent's PID
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

Every fork succeeds. How many processes reach puts("done") in this code?

if (fork() == 0) {
    fork();
}
puts("done");
  1. 2
  2. 3
  3. 4
  4. 5
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

A single-threaded program leaves "ready" pending in a fully buffered output stream, then forks successfully. Both processes call exit without further output. What can the destination receive?
  1. No copy, because fork clears pending output
  2. One copy, because the stream has one descriptor
  3. One copy only if the child exits first
  4. Two copies, because each process flushes a copied buffer
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

A process with PID 8502 successfully execs a new program. What is the new program's process ID?
  1. 8502
  2. 8503
  3. 0
  4. The parent's PID
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

A program is installed at /opt/course/bin/checker, and PATH includes /opt/course/bin. There is no file named checker in the current directory. Why does execv("checker", args) fail to locate it?
  1. Execv searches PATH only when args[0] is an absolute pathname.
  2. Execv searches only the directory of the calling executable.
  3. Execv treats the name as a pathname and does not search PATH.
  4. Execv searches PATH only after failing once in the current directory.
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

A child calls exit(515). After a successful wait and a true WIFEXITED test, what does WEXITSTATUS report?
  1. 515
  2. 512
  3. 255
  4. 3
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

A parent has one running child. Its waitpid(child, &status, WNOHANG) returns 0. What has happened?
  1. The child has exited successfully.
  2. No child result is ready, so the parent continues.
  3. The child no longer belongs to the parent.
  4. The parent has reaped a child with PID 0.
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

A server's child has state Z. Sending SIGKILL leaves the entry visible. What action releases this child's retained result record?
  1. The parent collects it with a wait operation.
  2. The child handles SIGTERM and calls exit.
  3. The scheduler grants the child another CPU turn.
  4. The parent sends SIGCONT and then SIGSTOP.
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

A shell redirects a child's standard output to a file and execs a command. The command writes normally, exits successfully, and the shell prompts again. What explains why the command required no redirection code?
  1. The parent forwards the child's output after wait returns.
  2. Exec interprets the redirection text in the argument vector.
  3. The child's descriptor setup survives program replacement.
  4. Exec gives the command a fresh copy of the parent's descriptors.
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

A shell starts producer | consumer. The producer exits, but the consumer waits forever after reading all available bytes. The shell closed its pipe copies; the consumer still holds its inherited original write-end descriptor. What fixes the hang?
  1. Wait for the consumer before closing the shell's read end.
  2. Close the unused write end in the consumer before exec.
  3. Close the consumer's read end when the producer exits.
  4. Have the shell collect the producer before starting its read.
Show answerHide answer

Save this lesson to see this answer.

Set 3: Follow kernel entry and CPU switching10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

Why must changing the interrupt-handler table be privileged?
  1. To prevent user code from redirecting protected kernel entry
  2. To ensure every program uses a different system-call number
  3. To make all hardware events synchronous with user instructions
  4. To require a new process whenever a handler is entered
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

A C function formats several short messages in an output buffer and later transfers them with one write. What cost does this grouping reduce?
  1. The number of characters the application must format
  2. The amount of memory needed for the executable file
  3. The number of processes needed to hold the messages
  4. Repeated kernel-entry and system-call bookkeeping
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

A C wrapper returns -1 from open and errno is ENOENT. What should the caller conclude?
  1. The file opened successfully with an unusual descriptor.
  2. The request failed because the named file was not found.
  3. The request created a child that has not finished yet.
  4. The file was opened but the byte count was truncated.
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

A network controller reports that a packet arrived while a process was adding integers. What kind of kernel-entry event is this?
  1. A synchronous arithmetic exception
  2. A deliberate system-call trap
  3. An asynchronous hardware interrupt
  4. A software signal sent by the adding instruction
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

An instruction accesses a valid page that is not currently resident. The kernel loads the page successfully. How can execution continue?
  1. Skip the instruction because its result was already stored.
  2. Terminate the process because every exception is fatal.
  3. Create a new process to execute the remaining instructions.
  4. Retry the instruction with the needed page now available.
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

In a periodic timer model with one tick every 5 ms, how many timer ticks occur per second?
  1. 200
  2. 50
  3. 500
  4. 5000
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

A process enters the kernel for a nonblocking service. The handler finishes and returns to the same process. What occurred?
  1. A context switch without any privilege change
  2. A mode transition without a process context switch
  3. A process switch that preserved the original PID
  4. A replacement of the process's program through exec
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

On one logical CPU, A makes a nonblocking write that returns to A; a timer then enters the kernel and returns to A. Next A makes a blocking read and B resumes; B later exits through a system call and C resumes. No other kernel entries occur. How many user-to-kernel entries and process context switches occur?
  1. 4 kernel entries; 4 process switches
  2. 3 kernel entries; 2 process switches
  3. 4 kernel entries; 2 process switches
  4. 4 kernel entries; 3 process switches
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

An application places an address of protected kernel memory in a write buffer argument and makes a system call. Why does controlled entry alone not authorize the requested read from that address?
  1. The kernel must still validate the caller's buffer access.
  2. The service number alone authorizes every supplied buffer address.
  3. The wrapper's register setup already proves the pointer is accessible.
  4. The mode switch makes protected memory part of the user buffer.
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

A repeated CPU cycle provides 2 ms of useful execution followed by an 8 µs context-switch cost. What fraction of the cycle is spent switching, approximately?
  1. 4.00%
  2. 0.004%
  3. 0.80%
  4. 0.398%
Show answerHide answer

Save this lesson to see this answer.

Set 4: Trace process behavior and resource sharing10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

One logical CPU runs J for 3 ms. J then waits for I/O for 5 ms and needs 2 ms more CPU time. K is ready initially and needs 6 ms of CPU time. K runs whenever J blocks and continues until it finishes; switching cost is ignored. When do both finish?
  1. 10 ms
  2. 11 ms
  3. 14 ms
  4. 16 ms
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

Which stored value lets the kernel identify the next instruction when it resumes a paused execution context?
  1. The current directory
  2. The file offset
  3. The parent PID
  4. The program counter
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

A single-threaded process has private x equal to 6. Every fork succeeds. All processes reach puts. How many lines contain "9"?

pid_t p = fork();
if (p == 0) x += 3;
fork();
if (x == 9) puts("9");
  1. 2
  2. 1
  3. 3
  4. 4
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

Before a successful fork, a file descriptor refers to offset 0 in an open file containing "ABCDEFGH". The parent reads exactly three bytes, then the child reads exactly two bytes through the inherited descriptor. No other operations occur. What does the child read?
  1. "AB"
  2. "BC"
  3. "DE"
  4. "FG"
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

A child calls execvp for a program that does not exist. Its next statement prints an error. Why can that statement execute?
  1. Exec starts the new program alongside the old call path.
  2. Every successful exec returns once before replacing memory.
  3. The parent automatically executes all child error statements.
  4. The failed exec returns without replacing the old program.
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

A parent with two live children calls wait. A signal handler interrupts it, producing -1 and errno EINTR. What should the parent do to keep collecting children?
  1. Stop because both children have been reaped.
  2. Retry the wait instead of treating EINTR as completion.
  3. Decode the untouched status with WEXITSTATUS.
  4. Send SIGKILL to its own process-table entry.
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

A shell calls chdir only in a forked child to implement cd, waits for that child, then launches another command. Why does the next command begin in the old directory?
  1. Wait always resets the parent's directory to its startup value.
  2. Exec ignores every inherited current-directory setting.
  3. The child's directory change did not change the parent shell.
  4. Chdir requires the shell itself to execute in kernel mode.
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

A shell creates a pipe, forks only the producer, and waits for it before creating the consumer. The producer writes more than the pipe can hold. Why can the launch sequence stall?
  1. The producer blocks on a full pipe while no consumer can drain it.
  2. The parent's read-end copy consumes bytes only after wait returns.
  3. The producer reaches end-of-file when the pipe first becomes full.
  4. The producer cannot close its output until the parent is reaped.
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

A device service runs in a separate user-mode server and crashes. The OS restarts that service while unrelated applications continue. What kernel-design feature helps explain this outcome?
  1. All services share the same privileged address space.
  2. Every device request bypasses the kernel's protection rules.
  3. The scheduler guarantees every application runs in parallel.
  4. The service is isolated from the small privileged core.
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

The same program and input cause a page fault on one run but not another because the needed page is already resident. How should the first run's fault be classified?
  1. Asynchronous, because the two runs differed
  2. Synchronous, because the memory instruction caused it
  3. A hardware interrupt caused only by elapsed time
  4. A signal created directly by the C library buffer
Show answerHide answer

Save this lesson to see this answer.

Set 5: Diagnose process and kernel interactions10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

A program has private x equal to 2. Every fork succeeds. How many processes print "hit"?

pid_t p = fork();
if (p > 0) {
    x = 7;
    fork();
}
if (x == 7) puts("hit");
  1. 2
  2. 3
  3. 4
  4. 1
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

A child's result passes WIFSIGNALED after waitpid succeeds. What macro gives the terminating signal number?
  1. WEXITSTATUS(status)
  2. WIFEXITED(status)
  3. WTERMSIG(status)
  4. WNOHANG
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

A write wrapper reports that 5 bytes were written from a requested 9-byte buffer. How many requested bytes still need to be transferred?
  1. 4 bytes
  2. 5 bytes
  3. 9 bytes
  4. 14 bytes
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

A process reads an invalid address on Linux, and the kernel delivers SIGSEGV. What sequence distinguishes the two events?
  1. A process signal is followed by a CPU memory exception.
  2. An asynchronous device interrupt is delivered directly as SIGSEGV.
  3. A deliberate system-call trap requests delivery of SIGSEGV.
  4. An instruction exception is followed by an OS signal to the process.
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

An OS enforces user-mode restrictions and receives timer interrupts. Its timer handler saves user registers but always returns to the same process. A proposed fix changes only how frequently the timer fires. Other processes remain ready. Why can this fix still fail to give them CPU turns?
  1. Timer entry itself guarantees fair turns before the handler returns.
  2. Regaining control supplies a mechanism, not a fair selection policy.
  3. User-mode limits make every ready process run at the next timer tick.
  4. Saving user registers automatically advances to the next ready process.
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

A workload repeats useful CPU turns of 600 µs with 6 µs switching cost. It changes to 1200 µs turns with the same cost. How does the switching share change?
  1. It rises from about 0.50% to about 0.99%.
  2. It falls from about 0.99% to about 0.50%.
  3. It stays at about 1% because switch cost is unchanged.
  4. It falls from about 9.9% to about 5.0%.
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

A shell opens an input-redirection file and receives descriptor 0 because standard input was closed. It calls dup2(fd, 0), closes fd unconditionally, and execs the command. Why can the command's standard input be closed?
  1. Closing fd closes only an old entry; descriptor 0 remains a distinct copy.
  2. Exec closes descriptor 0 because dup2 set its close-on-exec flag.
  3. dup2 rejects matching descriptor numbers and removes the input entry.
  4. Fd already equals 0, so closing fd closes the intended input.
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

A shell launches two children. One exits normally with status 0; the other is terminated by a signal. The shell must report both outcomes. What result-handling approach is required?
  1. Collect both children once, then decode both as normal exits.
  2. Collect one result and decode it once as an exit and once as a signal.
  3. Collect both results and select decoding macros separately for each.
  4. Collect both results but decode their raw integers as exit codes.
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

A blocks in a terminal read and B runs. After input makes A ready, the scheduler selects A. A proposed switch restores A's user program counter but retains B's kernel stack and address-space context. Why can this not correctly resume A's pending read?
  1. A's user return frame automatically restores the rest of its kernel path.
  2. Changing the user program counter also selects the matching kernel stack.
  3. The read can finish on B's kernel stack using only A's user registers.
  4. A's own kernel context, stack, and address-space context must be selected.
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

A user program knows the address of a kernel routine and the number of a valid system call. Why can it request the service but not simply call that privileged address as an ordinary function?
  1. A trap enters a configured kernel path that validates and dispatches the request.
  2. A direct call gains privilege whenever its target matches a valid service number.
  3. A service number grants the caller kernel access before its arguments are checked.
  4. A direct call and a trap both inherit privilege from the target address alone.
Show answerHide answer

Save this lesson to see this answer.

Stuck on your own question? Homework Help

Key Terms

75 Key Terms, each with its definition

A

Abstraction
An abstraction is a useful interface or model that hides lower-level implementation details while preserving operations programs need.
The file abstraction lets a program read bytes without knowing the storage device's command format.
Address space
An address space is the set of memory addresses available to a process and the code, data, heap, and stack mapped into that view.
Equal virtual addresses in two private address spaces can refer to different values in physical memory.
Argument vector
An argument vector is a null-pointer-terminated array of string pointers supplied to a new program as its command-line arguments.
An argument vector for a count command has separate entries for the program name, option, and filename.

B

Background job
A background job is work launched without the shell immediately waiting for its completion, allowing command input to continue.
The shell prompts while a background job runs but must still reap the child when that job finishes.
Batch processing
Batch processing collects submitted jobs and runs them without interactive input from the person who submitted each job.
In batch processing, a submitted calculation waits for earlier jobs instead of receiving an immediate turn.
Blocked state
The blocked state means a process cannot continue until an event occurs, such as requested input becoming available.
A blocking terminal read puts a process in the blocked state until input allows the request to proceed.
Built-in command
A built-in command is an operation implemented by the shell itself, allowing it to change the shell's own persistent process state.
The cd built-in changes the shell's directory so later commands inherit the newly selected directory.

C

Child process
A child process is a new process created by a parent, with its own identity and a copy of the parent's ordinary private memory.
The child process can change a private variable after fork without changing the parent's value.
Close-on-exec
Close-on-exec is a descriptor flag that requests automatic closure of that descriptor when a process successfully replaces its program.
A shell can keep an internal descriptor from reaching the command by marking that descriptor close-on-exec.
Concurrency
Concurrency means several activities are in progress during the same period, including when their instructions are interleaved.
Two programs are concurrent on one logical CPU when each repeatedly gets a turn before either finishes.
Context switch
A context switch saves one execution context and restores another; a process switch also selects the appropriate address space.
When a reader blocks, a context switch lets a ready computation resume on the same logical CPU.
Cooperative control
Cooperative control relies on programs yielding, making system calls, or causing exceptions for the OS to regain CPU execution.
An endless user loop exposes cooperative control's weakness if it never reaches any path back to the OS.
Copy-on-write
Copy-on-write initially shares protected physical memory pages and makes private copies when writes require separate contents.
A child that immediately calls exec can discard inherited pages without first copying every page.
CPU utilization
CPU utilization is the fraction of an elapsed interval during which the CPU is busy, expressed as a proportion or percentage.
If useful computation occupies 9 ms in a 12 ms trace with no overhead, CPU utilization is 75%.

E

End-of-file
End-of-file is a read result indicating no more data is available; for a pipe it requires an empty buffer and no open writers.
A reader can wait instead of receiving end-of-file if the shell accidentally retains a pipe write end.
errno
errno is a C library error indicator set by many interfaces on failure and inspected after the return value reports an error.
A failed open can set errno to ENOENT, while a later successful call need not clear that earlier value.
Exception
An exception is an event arising from the current instruction that requires special CPU and kernel handling, such as a page fault.
A forbidden memory access raises an exception before the application can continue normally.
Exception level
An exception level is an AArch64 execution privilege level, including EL0 for applications and normally EL1 for the OS kernel.
AArch64 names privilege levels differently from x86 rings while still separating applications from the kernel.
Exec
Exec replaces the calling process's program image with a new program while preserving process identity and selected resources.
The child keeps its PID when exec replaces the shell's code with the requested command's code.
Exit status
An exit status is the small result a process reports on normal termination, conventionally 0 for success and nonzero for failure.
After checking normal termination, the parent extracts the exit status with the appropriate wait macro.

F

File descriptor
A file descriptor is a small integer in a process's descriptor table that refers to an open file or another I/O resource.
A shell connects file descriptor 1 to a file before executing a command whose output is redirected.
Fork
Fork is the Unix process-creation operation that makes a child and returns to both parent and child after the same call.
After a successful fork, the parent receives the child's PID and the child receives a return value of 0.

H

Hardware interrupt
A hardware interrupt is a device or timer notification that makes the CPU handle an event independently of the current instruction.
A storage controller raises a hardware interrupt when a previously requested transfer completes.

K

Kernel
The kernel is the privileged core of an operating system that controls protected hardware operations and manages process resources.
A terminal application asks the kernel to read input instead of controlling the keyboard device itself.
Kernel context
A kernel context is the saved register and stack state needed to resume the kernel's execution path for a suspended process.
When switching to process B, the switch routine restores B's kernel context before kernel exit code can restore B's user registers.
Kernel mode
Kernel mode is the CPU privilege level that permits the OS to manage protected hardware state and privileged instructions.
The CPU enters kernel mode to handle a request made by an ordinary user's application.
Kernel stack
A kernel stack holds saved user state and kernel execution data while the kernel runs on behalf of a process or execution context.
Switching to another process includes restoring the kernel stack used by that process's saved return path.

L

Library wrapper
A library wrapper is user-space code that presents a callable interface and arranges the arguments and entry for a kernel service.
The write library wrapper follows the system-call register convention before entering the kernel.
Limited direct execution
Limited direct execution runs user instructions on hardware while privilege limits and timer-driven entry preserve OS control.
A looping application executes directly but still cannot disable the timer that can interrupt it.

M

Mechanism
A mechanism is the means for carrying out an OS operation, such as preserving one process's state and restoring another's.
The context-switch mechanism supports several possible rules for deciding which ready process runs next.
Microkernel
A microkernel keeps a small privileged core and places more OS services in separate user-mode processes that communicate by messages.
A failed user-mode driver in a microkernel design can often be restarted while other services continue.
Mode switch
A mode switch changes the CPU privilege level, such as entering the kernel for a service and returning to the same user process.
A nonblocking system call can involve mode switches without resuming a different process.
Monolithic kernel
A monolithic kernel runs most OS services together in kernel mode, allowing direct calls but sharing the risks of privileged faults.
A Linux driver module joins the monolithic kernel and can damage kernel state if it contains a serious bug.
Multiprogramming
Multiprogramming keeps several jobs available in memory so one can use the CPU while another is blocked for I/O.
Multiprogramming lets a compiler compute while a different process waits for a storage read to finish.

N

Nonblocking wait
A nonblocking wait checks for an available child result and returns without suspending the caller when no result is ready.
A shell uses a nonblocking wait to collect completed background jobs while keeping the prompt available.

O

Open file description
An open file description is kernel-maintained state for an open file, including its offset, that multiple descriptors can share.
Parent and child reads through an inherited descriptor advance the offset in one open file description.
Operating system
An operating system manages hardware resources and provides services that let programs run, communicate, and store data safely.
The operating system shares CPU time between a browser and a compiler while managing their file requests.
Orphan
An orphan is a process whose parent has exited and that is reparented so another process can later collect its result.
An orphan can continue computing after its original parent exits; it has not necessarily terminated.
Output buffer
An output buffer is user-space storage that holds formatted output before a library transfers those bytes to the kernel.
Pending text in an output buffer can be copied by fork and later flushed once by each process.
Overhead
Overhead is the extra time or memory spent managing an operation instead of directly performing the application's useful work.
Saving registers during a context switch adds overhead before another process resumes computation.

P

Page fault
A page fault is an instruction-caused event from a memory access whose translation or permissions require special handling.
A valid absent page can be loaded after a page fault, letting the kernel retry the interrupted instruction.
Parallelism
Parallelism means work executes at the same instant on separate processing resources, such as different logical CPUs.
A compiler and a renderer can execute in parallel when each is running on a different logical CPU.
Parent process
A parent process is the process that creates a child; it can use waiting operations to collect that child's termination result.
A shell remains the parent process while its child replaces its own program with an external command.
PATH
PATH is an environment variable listing directories searched for executable names by interfaces such as execvp.
A command found through PATH can start with execvp even when its file is not in the current directory.
Pipe
A pipe is a kernel-managed one-way byte channel with a read end and a write end that can connect cooperating processes.
A shell connects a producer's output to a pipe and a consumer's input to the same pipe's read end.
Policy
A policy is a rule for choosing how to use available mechanisms, such as deciding which ready process should receive CPU time.
A scheduling policy can change while the register-saving code used to switch processes stays the same.
Privileged instruction
A privileged instruction changes protected machine state and cannot be freely executed by ordinary user-mode code.
Disabling interrupts is privileged because it could otherwise prevent the OS from regaining control.
Process
A process is an active instance of a program together with the memory, register values, and I/O state needed for its execution.
Two processes running the same executable can keep different private variables and current directories.
Process control block
A process control block (PCB) is the kernel's record of one process, including its identity, state, resources, and saved context.
The kernel consults a process control block to find a stopped process's memory information and parent.
Process ID
A process ID (PID) is a numeric identifier assigned to a process and unique among live processes in the same PID namespace.
A process listing uses PID and parent PID to show that a command was launched by a particular shell.
Program
A program is stored instructions and data that can be loaded for execution; the file itself has no changing execution state.
The same shell program file can be used to start separate processes in three terminal windows.
Program counter
The program counter is a CPU register holding the address of the next instruction in an execution context.
Restoring the program counter lets a paused process continue at the correct instruction after a switch.
Protection ring
A protection ring is an x86 hardware privilege level; mainstream systems normally use ring 0 for kernels and ring 3 for applications.
Crossing from application ring 3 to kernel ring 0 follows a controlled entry path configured by the OS.

R

Ready state
The ready state means a process can execute but is waiting for a CPU to become available or for the scheduler to select it.
A timer can move an unfinished computation from the running state to the ready state without any I/O.
Reaping
Reaping is collecting a terminated child's result with a wait operation so the kernel can release its remaining process record.
One successful wait reaps one child; a parent with several children must continue collecting results.
Redirection
Redirection changes a command's standard input, output, or error descriptor to refer to a different open I/O resource.
Output redirection lets an unchanged program write its ordinary standard output into a chosen file.
Return from trap
A return from trap restores saved execution state and returns from kernel handling to the intended user execution context.
The OS can prepare a new process's initial state so the restoration path starts that program for the first time.
Running state
The running state means a process is currently executing instructions on a CPU, in contrast to being eligible or waiting for an event.
When a ready compiler receives a CPU, it enters the running state and can execute its next instruction.

S

Scheduler
The scheduler is the OS component that chooses which eligible execution context should receive CPU time next.
After a disk read completes, the scheduler may keep the current process running before selecting the reader.
Shell
A shell is a user program that interprets commands and uses process and descriptor operations to launch and connect other programs.
A foreground shell waits for its command's child process before displaying the next prompt.
Signal
A signal is a software notification delivered by the OS to a process, with a default action or an installed handling behavior.
A terminal sends SIGINT to its foreground job when the user presses Ctrl-C, normally ending the job.
Space sharing
Space sharing divides a resource's capacity into portions that different processes or users hold at the same time.
Separate memory regions can remain assigned to several processes while only one has the CPU.
Stack pointer
The stack pointer is a register that locates the current position of a stack used for function calls and execution state.
A context switch restores the stack pointer so the resumed execution uses its own saved stack.
System call
A system call is a controlled request from a user program for a kernel service, made through a defined entry interface.
Opening a file requires a system call because kernel code manages access to the open-file resource.
System-call number
A system-call number is an architecture-specific identifier the kernel dispatches to a particular service implementation.
Linux uses different system-call numbers for write on x86-64 and AArch64, so raw numbers are not portable.

T

Time sharing
Time sharing divides access to a resource into successive turns, allowing several processes or users to share it over time.
Time sharing gives an editor another CPU turn while a long calculation is still in progress.
Time slice
A time slice is an interval of CPU execution allotted to work before scheduling may give another eligible process a turn.
With fixed switch cost, making a time slice shorter increases the fraction of time spent switching.
Timer interrupt
A timer interrupt is a hardware event from a configured timer that gives the kernel an opportunity to regain control of a CPU.
A timer interrupt can enter the kernel even while the current process runs a loop without system calls.
Translation lookaside buffer
A translation lookaside buffer (TLB) caches address translations so the CPU can avoid repeatedly looking them up in memory.
A process switch can require translation refills, although tagged entries can preserve useful cached translations.
Trap
A system-call trap is deliberate kernel entry caused by a program's service request, using a protected entry instruction.
The request to write output causes a system-call trap even when there is no error in the program.
Trap table
A trap table maps event kinds to protected kernel handler destinations, with the exact organization depending on the CPU.
At boot, the OS prepares handler destinations so user code cannot redirect a later kernel entry.

U

User mode
User mode is the CPU privilege level that runs application instructions with restricted access to protected memory and operations.
An administrator's editor still runs in user mode and uses system calls to request protected services.

V

Virtualization
Virtualization presents a shared physical resource as a convenient virtual resource that each program can use through a simpler view.
CPU virtualization lets hundreds of processes make progress on a machine with only a few logical CPUs.

W

Wait status
A wait status is an encoded value describing how a child ended or changed state, interpreted through the matching wait macros.
A Linux raw wait status of 768 can encode normal exit code 3, so printing it directly gives the wrong code.

Z

Zombie
A zombie is a terminated process whose kernel result record remains because its parent has not yet collected that result.
A long-running server prevents zombie accumulation by reaping the children that have finished.

About this lesson

By StudeliReport a mistake

Make your own Study Materials

Turn your notes, slides and documents into Study Guides, Practice Questions, Flashcards and 6 more tools.

Get Started