Threads
Threads Basics
- unit of task/execution
- logically divide a program into independent tasks / threads
- a process = address space + os resources + 1 or more threads
- threads share the same address space, share the same code, data, and heap region
- threads share the same OS resources (e.g. open files), read by one thread advances file offset for all threads
- threads have their own execution states: own user stack, pc, sp, registers
- can threads access each other's user stack?
- what about kernel stack? should each thread have its own kernel stack?
- what is the cost of starting a new process vs a new thread?
- threads are managed and scheduled by the kernel
- Thread Control Block (TCB)
- tid, sp, registers, kernel stack, pointer to PCB
- context switch: switch from one thread to another thread
- first save the current thread's registers (context) so it can resume at its next turn
- then switch to the next thread's kernel stack and load in saved registers (context)
- if the next thread belongs to a different process, switch to the new address space and flush the TLB
- xk flow: current thread -> scheduler -> next thread
- scheduler is a thread in the kernel address space, doesn't belong to any process
- POSIX threads (pthreads) API
- pthread_create: creates a new thread, pass in a thread_func (PC for the new thread) and args
- pthread_join: wait for a specific thread to terminate & free its resources, any thread can join other threads
- pthread_exit: when the last thread of a process exits, the process terminates
- pthread_detach: upon exit, automatically frees resources without join, unjoinable
Threads Execution
- a thread's execution may be interrupted at anytime
- threads can interleave in many ways
- what may happen when multiple threads read and write shared states?
- time-of-check to time-of-use: shared state might be modified by another thread
- will this always cause a problem?
- race condition: different scheduling orders can lead to results that are semantically different
- reasoning about multithreaded code without protection is difficult!