Processes and Threads
Learning outcomes:
- Explain the difference between a program, a process, and a thread
- Describe the process states and the transitions between them, and identify them on a Linux system
- Explain what a process control block stores, and how interrupts and context switches let a system run many processes
- Compare user-level and kernel-level threads, and explain why modern apps use multiple processes and threads
Would you like to download my PowerPoint to follow along?
- Processes and Threads
- A program is a recipe. A process is someone actually cooking it
- One program can run as several processes, such as two windows of the same app
- A process is a program in memory that is running, or waiting for the CPU, I/O, or another service
- Computers do many things at once: play music, load a web page, download a file, and check email
- Processes let the OS keep track of all of them (Microsoft: About processes and threads)
- What's Inside a Process
- Each process gets its own private section of memory, called its address space
- Code (text): the instructions the CPU runs
- Data: the information the program is working with
- Stack: the program's to-do list, tracking which task it's in the middle of
- One process can't read another process's memory, which keeps programs from interfering with each other
- Process Creation
- A new process is created when:
- You open an app or type a command
- A user logs in
- The system starts a service at boot. On Linux, systemd does this (systemd)
- A running process creates another one
- A process is created if there's enough memory, and it waits if other resources it needs aren't available
- Process Behavior
- A process needs the CPU and I/O at different times, and usually has to wait for them
- The OS keeps a waiting line (queue) for each of these services
- At one moment a process may be in line for the CPU, and later in line for the drive or the network
- When it has finished everything it needs to do, the process ends (terminates)
- Process States
- New: being created
- Ready: waiting in line for the CPU
- Running: using the CPU right now
- Blocked (waiting): waiting for I/O or some other event, like a file to load or a key press
- Terminated: finished, and being cleaned up
- Some systems add suspended states for processes moved out of memory (see the diagrams below)
- Process State-Transition Diagrams
- Diagrams: a process is created, waits in Ready, runs, and can be interrupted back to Ready, block while waiting for I/O or a resource, or terminate. The simpler version shows Ready, Running, and Blocked, with dispatch, timer runout, block, and wakeup moving a process between them
- Diagram: the same states plus suspend and resume. A suspended process is moved out of memory until it is resumed
- Process States on Linux
- ps and top show each process's state as a letter (Linux manual page: ps)
- R: running, or ready to run
- S: sleeping (blocked, waiting for an event)
- D: waiting on a device, usually the disk, and can't be interrupted
- T: stopped, such as after pressing Ctrl+Z
- Z: zombie. Finished, but its parent hasn't collected its exit status yet
- A few zombies are harmless. Lots of them usually means a buggy parent program
- Process Control Block (PCB)
- The PCB holds everything the OS needs to manage a process, such as:
- Process ID number (PID)
- Process state
- Program counter: where it is in the code
- Scheduling priority
- Credentials: which user it runs as
- Its parent process and child processes
- Where its code and data are in memory
- Resources it has, such as open files
- On Linux, the PCB is called the task_struct
- PCB Example
- Example: the process table lists each PID and points to that process's PCB
- Process Operations
- A process may create (spawn) a new process
- The creating process is the parent, and the new one is the child
- Each child has exactly one parent, so processes form a tree
- When a parent ends, the OS either ends its children too, or lets them keep running
- On Linux, orphaned children are adopted by process 1 (systemd)
- Process Tree Example: Linux
- Historical note: this older tree starts with init, and shows kernel helpers like khubd and pdflush that modern Linux no longer has
- Today most distros start systemd as process 1, and it starts everything else
- Run pstree to see your own system's tree (Linux manual page: pstree)
- Interprocess Communication (IPC)
- Processes often need to share data or work together
- Common ways:
- Pipes: one program's output feeds into the next. In a Linux shell, ls | grep txt is a pipe (Linux manual page: pipe)
- Signals: short alerts. Ctrl+C sends one to stop a program, and kill sends one to a process ID (Linux manual page: signal)
- Sockets: connections between processes, even on different computers. This is how your browser talks to websites
- Shared memory: two processes share one section of memory
- Message Passing
- One process sends a message, and another receives it
- Messages can go one way, or both ways
- Blocking: the sender waits until the message is received
- Nonblocking: the sender keeps working without waiting
- Like a phone call, where you wait for an answer, compared with a text message, where you send it and keep going
- Processes on Linux and Unix
- Every process has a process ID (PID) and its own private memory space
- The kernel keeps each PCB in protected memory that programs can't touch
- Processes ask the kernel for help through system calls (Week 1)
- fork creates a copy of a process. This is how the shell starts each command you type
- Nice values run from -20 to 19. Lower numbers mean higher priority (Linux manual page: nice)
- nice and renice change them, and top shows them in the NI column
- Seeing and Stopping Processes
- Windows: Task Manager (Ctrl+Shift+Esc). Select a frozen app and choose End task (Microsoft Learn: Task Manager)
- macOS: Activity Monitor, or Force Quit (Option+Command+Esc) (Apple: How to force an app to quit)
- Linux: top, htop, or ps aux show what's running (htop)
- kill followed by a process ID asks a program to stop. kill -9 forces it (Linux manual page: kill)
- Forcing a program to quit can lose unsaved work, so try closing it normally first
- Modern Apps Use Many Processes
- Web browsers run websites in separate processes (Chromium: Site Isolation)
- Chrome calls this Site Isolation, and Firefox calls it Project Fission (Mozilla: Project Fission)
- One crashed tab doesn't take down the others, and a bad site can't easily read another site's data
- That's why Task Manager may show dozens of browser processes
- Phones stop background apps to save battery and memory (Android: Processes and app lifecycle)
- Android and iOS can end an app you aren't using, and restart it when you come back (Apple: Managing your app's life cycle)
- Threads
- A thread is one path of work inside a process
- If a process is a kitchen, threads are the cooks: they share the space and ingredients, but each does a different task
- Threads share the process's code, memory, and open files, but each has its own place in the code and its own stack
- Most programs today use several threads
- A game can draw graphics, play sound, and load the next level at the same time
- Why threads?
- Easier to split up work that can happen at once
- Spread work across several processor cores
- Sharing memory is faster than passing messages between processes
- Threads in a Process
- The OS manages both processes and threads
- Switching between threads is faster than switching between processes, because they share memory
- Each thread has a small record of its own (a thread descriptor): ID, state, priority, and its stack
- A process starts with one thread, the main thread, and can create more
- Life Cycle of a Thread
- Diagram: a thread is born, becomes ready, runs, and can wait for an event, sleep, block on I/O, or finish (dead)
- Threading Models
- Who manages the threads, the program or the kernel?
- User-level threads: the program manages them
- Kernel-level threads: the operating system manages them
- A mix of both (many-to-many)
- Today, Linux and Windows use one-to-one: every thread is a kernel-level thread
- Programmers create threads with libraries, such as POSIX threads (Pthreads) on Linux, or Java's thread classes (Linux manual page: pthreads)
- User-level Threads
- The program manages its own threads with a thread library, and the kernel doesn't know they exist
- Fast to create and switch between
- But if one thread blocks, the whole process blocks, and it can only use one core
- Kernel-Level Threads
- The kernel creates and schedules each thread
- If one thread blocks, the others keep running
- Threads can run on several cores at the same time
- Linux and Windows work this way today (one-to-one)
- Combining User- and Kernel-level Threads
- Many-to-many: many user threads share a smaller number of kernel threads
- Historical note: popular in older systems like Solaris, but Linux and Windows moved to one-to-one. Still worth knowing because it's back: Go's goroutines and Java's virtual threads (2023) work this way (Java: JEP 444, Virtual Threads)
- Thread pools: worker threads that stay ready, so new tasks don't wait for a thread to be created. Web servers use them
- Scheduler activations: the kernel tells the program's thread library when one of its threads blocks, so the library can run another
- Diagram: three processes with different numbers of user threads, mapped onto a smaller number of kernel threads
- Multi-Core Processors
- A core is a complete processor, and most computers and phones today have several (IBM: What is a CPU?)
- Each core can run a different thread at the same time
- Hyper-threading (simultaneous multithreading) lets one core juggle two threads
- Newer chips mix fast performance cores with power-saving efficiency cores (Intel: How Intel Core processors work)
- Apple silicon, recent Intel Core chips, and most phone processors do this
- The OS decides which threads go on which cores (Week 5, Processor Scheduling)
- Interrupts and Context Switches
- The CPU switches between processes so fast it looks like they all run at once
- Running many processes this way (multiprogramming) is covered in Week 4
- Interrupt: a signal that makes the CPU stop and deal with something
- Context switch: the CPU saves one process and loads another
- The scheduler decides which process runs next (Week 5)
- Context Switch
- The OS saves the current process's state (its place in the code, its registers, and more) into its PCB, then loads the next one's
- Like putting a bookmark in one book before picking up another
- Switching is overhead: time spent switching instead of doing real work
- How fast it is depends on the hardware
- Interrupts
- Interrupts let the system respond to events right away, instead of constantly checking (more on this in the Storage, I/O, and Backups week)
- Traps: caused by the running program itself, such as dividing by zero or touching memory it isn't allowed to use
- Hardware interrupts: caused by outside events, such as a key press, a mouse move, or a finished download
- Handling an interrupt:
- The CPU finishes its current instruction and pauses the process
- It runs the kernel's interrupt handler, found in a table called the interrupt vector
- Then it goes back to the process, or switches to another one
- Linux Threads
- Linux treats processes and threads the same way: both are tasks
- fork creates a new process. clone creates a new task and chooses what to share with the parent (Linux manual page: clone)
- Share everything, and the new task is a thread
- See threads with top -H or ps -eLf
- The diagram in the PowerPoint shows the states a Linux task moves through: created, active, running, expired, sleeping, stopped, zombie, and dead
- Containers: Groups of Processes
- A container is a group of processes kept separate from the rest of the system (Red Hat: What is a Linux container?)
- They get their own view of files, the network, and other processes
- Containers share the host's kernel, so they start fast and use little memory
- Docker and Kubernetes run apps this way. More in Week 14, Virtual Machines
Suggested Activities and Discussion Topics:
- Activity: open Task Manager (Windows), Activity Monitor (Mac), or run top (Linux). How many processes and threads are running right now? Which one is using the most CPU?
- Activity: on a Linux system or virtual machine, run pstree. What is process 1 called? Can you find the shell you're typing in, and the processes it started?
- Activity: in top, look at the S column. Which states can you find (R, S, D, T, Z)? Press Shift+H to switch to showing threads. How does the number change?
- Discussion: open several tabs in your web browser, then look at Task Manager or Activity Monitor. How many browser processes are there? Why would browser makers design it this way?
- Discussion: why might your phone close an app you weren't using? What would happen if it never did?
Would you like to see some more classes? Click here