Lecture 7 about 35 min 20 quiz questions

Threads

What a thread is, what it shares and what it owns, why threads beat processes for many jobs, and how user threads map onto kernel threads in the many-to-one, one-to-one, many-to-many, and two-level models.

What you will be able to do

  • Define a thread and list exactly what is private to a thread versus shared across a process.
  • Explain the four benefits of multithreading with a concrete example for each.
  • Contrast user-level and kernel-level threads on creation cost, blocking behaviour, and multiprocessor use.
  • Describe the many-to-one, one-to-one, many-to-many, and two-level models with their example systems.
  • Work out how many threads can truly run in parallel given a model, kernel thread count, and core count.
1

What a thread is

A lightweight process: its own program counter, registers, and stack, but shared everything else.

A thread, sometimes called a lightweight process (LWP), is the basic unit of CPU utilisation. It comprises a thread ID, a program counter, a register set, and a stack. It shares with the other threads of the same process the code section, the data section, and other OS resources such as open files. A traditional heavyweight process has a single thread of control. Give it several and it can do more than one task at a time.

single-threaded processcodedatafilesshared by the whole processregistersstackthreadmultithreaded processcodedatafilesshared by the whole processregistersstackthreadregistersstackthreadregistersstackthread
Single-threaded: one stack, one set of registers, one program counter. Multithreaded: code, data, and files shared; each thread carries its own registers, stack, and program counter.

Per-thread versus per-process

Private to each threadShared by all threads in the process
Thread IDCode section (the program text)
Program counterData section (globals, heap)
Register setOpen files and other OS resources
Stack (local variables, return addresses)Address space and memory mapping

A multithreaded process has three parts

  • Address space: the code and data of the process.
  • Threads: individual execution contexts.
  • Resources: the physical support needed to run, such as memory and disk.
Shared data, private stacks (pthreads sketch)c
1#include <pthread.h>
2#include <stdio.h>
3
4int shared_counter = 0; /* data section: visible to every thread */
5
6void *worker(void *arg) {
7 int local = *(int *)arg; /* on THIS thread's stack: private */
8 shared_counter += local; /* touches the shared data section */
9 return NULL;
10}
11
12int main(void) {
13 pthread_t t1, t2;
14 int a = 1, b = 2;
15 pthread_create(&t1, NULL, worker, &a);
16 pthread_create(&t2, NULL, worker, &b);
17 pthread_join(t1, NULL);
18 pthread_join(t2, NULL);
19 printf("%d\n", shared_counter);
20 return 0;
21}

Output

3   (usually; the unsynchronised += is a race, which is Lecture 9's problem)
1 of 5
2

Four benefits of threads

Responsiveness, resource sharing, economy, and multiprocessor utilisation.

The four benefits from the slides

  1. 1

    Responsiveness

    A multithreaded interactive application keeps running even if part of it is blocked or doing a lengthy operation. The browser keeps rendering while another thread waits on the network.

  2. 2

    Resource sharing

    Processes can only share through shared memory or message passing, which the programmer must arrange explicitly. Threads share the memory and resources of their process by default, so several threads of activity can live in one address space.

  3. 3

    Economy

    Allocating memory and resources for a new process is costly. Threads are inexpensive to create, destroy, and represent. With so little context, switching between threads is much faster.

  4. 4

    Utilisation of multiprocessor architectures

    A single-threaded process can run on only one CPU no matter how many exist. Multithreading on a multi-CPU machine increases concurrency: each thread may run in parallel on a different processor.

What a thread needs space for

Must store per thread

  • Program counter (PC)
  • Stack pointer (SP)
  • General-purpose registers

Does not need per thread

  • Shared memory information
  • Information about open files and I/O devices
  • Code
  • Data
2 of 5
3

Process versus thread, multiprocessing versus multithreading

Same goal, concurrency. Very different price tags.

Process versus thread

AspectProcessThread
WeightHeavyweightLightweight
Address spaceOwn, isolatedShared with sibling threads
Creation and termination costHigh: memory, PCB, resourcesLow: only PC, SP, registers, stack
Context switchSlow: address space changesFast: no address space change
CommunicationIPC needed: shared memory or message passing, set up explicitlyShared data by default
ProtectionOne process cannot corrupt anotherOne thread can corrupt another's data
If one blocksOthers unaffectedDepends on the threading model (see below)

Multiprocessing versus multithreading

Multiprocessing

  • Many processes, each with its own address space
  • Isolation and robustness: a crash stays contained
  • Expensive to create and switch
  • Example: a browser that runs each tab as a separate process

Multithreading

  • Many threads inside one process, one address space
  • Cheap creation, fast switching, easy data sharing
  • One bad thread can bring down the process
  • Example: a word processor's UI, keystroke, and spellcheck threads
3 of 5
4

User-level and kernel-level threads

Who knows the thread exists: a library in user space, or the kernel?

Support for threads can be provided at the user level, giving user threads, or by the kernel, giving kernel threads. The distinction is about who creates, schedules, and manages them.

User-level threads

  • Supported above the kernel and implemented by a thread library in user space.
  • The library handles creation, scheduling, and management with no kernel support.
  • The kernel is unaware of them. Everything happens in user space without kernel intervention.
  • Consequences: no kernel resources allocated per thread, and switching does not change the address space, so they are fast to create and manage.

Kernel-level threads

  • Supported and managed by the kernel. Creation, scheduling, and management happen in kernel space.
  • Generally slower to create and manage than user threads.
  • If one thread makes a blocking system call, the kernel can schedule another thread of the same application.
  • On a multiprocessor, the kernel can schedule threads of one process on different processors.

User-level versus kernel-level threads

User-level threadsKernel-level threads
Managed byThread library in user spaceThe operating system kernel
Kernel awarenessKernel does not know they existKernel schedules each one
Creation and managementEasier and fasterSlower
Thread switchNo kernel-mode privilege or mode switch neededRequires a mode switch to kernel mode
Blocking system callBlocks the entire processOnly that thread blocks; kernel runs another
Multiprocessor useCannot exploit multiple CPUsThreads of one process run on different CPUs
PortabilityRun on any operating systemDepend on kernel support
Kernel routinesNot applicableKernel routines themselves can be multithreaded
4 of 5
5

Multithreading models

How user threads map onto kernel threads decides what blocks and what runs in parallel.

many-to-oneuser spacekernel spaceuuuukone-to-oneuser spacekernel spaceuuuukkkkmany-to-manyuser spacekernel spacetwo-level: plus bound threadsuuuuukkkuser threads on top map to kernel threads below, only kernel threads are scheduled
Many-to-one: all user threads on one kernel thread. One-to-one: a kernel thread per user thread. Many-to-many: a pool of kernel threads. Two-level: many-to-many plus some bound threads.

The models, one by one

  1. 1

    Many-to-one (user-level threading)

    Many user threads mapped to a single kernel thread. Efficient because management is in user space. Shortcoming: the entire process blocks if any thread makes a blocking system call, and since only one thread can access the kernel at a time, threads cannot run in parallel on multiprocessors. Used on systems without kernel thread support. Examples: Solaris Green Threads, GNU Portable Threads.

  2. 2

    One-to-one (kernel-level threading)

    Each user thread maps to its own kernel thread. More concurrency than many-to-one: when one thread blocks, another runs. Multiple threads run in parallel on multiprocessors. Shortcoming: creating a kernel thread for every user thread is overhead that can burden the application. Examples: Windows 95/98/NT/2000, OS/2.

  3. 3

    Many-to-many (hybrid)

    Multiplexes many user threads onto a smaller or equal number of kernel threads. The OS creates a sufficient number of kernel threads. Suffers from neither shortcoming of the other two: developers create as many user threads as they like, the kernel threads run in parallel on a multiprocessor, and when one blocks the kernel schedules another. Examples: IRIX, HP-UX, Solaris 8.

  4. 4

    Two-level

    A popular variation of many-to-many that also allows a user thread to be bound to a specific kernel thread. Examples: IRIX, HP-UX, Tru64 UNIX, Solaris 8 and earlier.

Models compared

ModelKernel threadsOne thread blocksParallel on multicoreCostExamples
Many-to-one1Whole process blocksNoVery lowSolaris Green Threads, GNU Portable Threads
One-to-oneOne per user threadOnly that threadYesHigh per threadWindows 95/98/NT/2000, OS/2
Many-to-manyFewer than or equal to user threadsKernel runs anotherYes, up to kernel thread countModerateIRIX, HP-UX, Solaris 8
Two-levelPool plus bound threadsKernel runs anotherYesModerateIRIX, HP-UX, Tru64 UNIX, Solaris 8 and earlier
5 of 5

Before the exam

The lines worth memorising, and the mistakes that lose marks.

Remember this

  1. 1Thread = thread ID + program counter + register set + stack. Shares code, data, open files with its process.
  2. 2Lightweight process (LWP) is another name for a thread; a traditional process is heavyweight with one thread of control.
  3. 3Four benefits: responsiveness, resource sharing, economy, utilisation of multiprocessor architectures.
  4. 4Thread switch is faster because the address space does not change. Only PC, SP, and general registers move.
  5. 5Threads do not give memory protection between each other. Processes do.
  6. 6A single-threaded process uses one core no matter how many exist.
  7. 7User-level threads: library-managed, kernel unaware, fast to create, no mode switch, but a blocking call blocks the whole process and no multiprocessor use.
  8. 8Kernel-level threads: kernel-managed, slower, mode switch per switch, but a blocked thread lets siblings run and threads spread over CPUs.
  9. 9Many-to-one: one kernel thread, whole process blocks, no parallelism. Solaris Green Threads, GNU Portable Threads.
  10. 10One-to-one: kernel thread per user thread, parallel, but creation overhead. Windows 95/98/NT/2000, OS/2.
  11. 11Many-to-many: user threads multiplexed over a smaller or equal pool of kernel threads; neither shortcoming. IRIX, HP-UX, Solaris 8.
  12. 12Two-level: many-to-many plus the option to bind a user thread to a kernel thread. Adds Tru64 UNIX to the list.
  13. 13Max parallel threads = min(kernel threads, cores). 4 kernel threads on 2 cores gives 2.

Exam traps

  • Listing the stack as shared. Each thread has its own stack; the heap and globals in the data section are shared.
  • Saying a thread has its own code section. Code is shared; only the program counter into that code is private.
  • Claiming user-level threads can run in parallel on multiple CPUs. The kernel sees one schedulable entity, so no.
  • Thinking a blocking system call in a kernel-level thread blocks the process. Only that thread blocks; the kernel schedules another.
  • Picking one-to-one as 'best balance'. The slides give that to many-to-many; one-to-one pays a kernel thread per user thread.
  • Confusing concurrency with parallelism. Many-to-one has concurrency but never parallelism.
  • Counting kernel threads instead of cores when asked how many threads run at once. The answer is the smaller of the two.
  • Listing memory protection as a benefit of threads. Shared memory is the point; protection is what you give up.

Quiz yourself

One question at a time with instant feedback. Your best score is saved.

Timed version →
Q 1 / 20 · Thread anatomyeasyscore 0

Which component is unique to each thread?

Not quite

A thread owns its thread ID, program counter, register set, and stack. Code, data, and open files belong to the process and are shared.

Finished reading?

Mark this lecture as done

Take the quiz above first so your score is saved here.