COMP 3511: Lecture 10
Date: 2024-10-08 14:53:43
Reviewed:
Topic / Chapter:
summary
βQuestions
Notes
Threads (cont.)
-
Multithreading models (cont.)
-
Multithreading: many-to-one
- many user thread: mapped to single kernel thread
- only one user thread mapped to kernel thread at execution time
- which user thread is mapped: scheduling problem
- one thread blocking (of thread): causes
- cases all
- m
- no performance benefit
- still, structure-wise works like multithreading
- cannot run in parallel on multicore system
- as one kernel thread: can be active at a time
- examples
- Solaris Green Threads
- GNU Portable Threads
- π¨βπ« used in the past due to resource limitation
- kernel thread: requires resource
- user thread: piece of code waiting for execution
- few systems currently use this model
-
Multithreading: one-to-one
- each user-level thread: maps to one kernel threads
- maximum concurrency: allows multiple threads to run in parallel
- having more kernel threads than user threads: meaningless
- i.e. creation of user thread: mandates kernel thread creation
- max no. of threads / process: might be restricted due to overhead
- could have been problematic in the past
- as kernel thread consumes resources: memory, IO, etc.
- examples
- Windows
- Linux
-
Multithreading: many-to-many
- multiplexing many user=level
- in-between
- process-contention scope: to be discussed later (Ch. 5)
- π¨βπ« similar to many-to-one mapping
- we have scheduling problem
-
Multithreading: two-level
- similar to many-to-many
- but: it allows user thread to be bound to kernel thread
- e.g. some user thread: significant, and requires set kernel thread
-
Multithreading mapping models
- many-to-many: most flexible
- but difficult ti implement in practice
- in modern computer: limiting no. of kernel threads: less of a problem
- thanks to multi core
Threading Issues
-
fork()
,exec()
semantics- does
fork()
by thread: duplicate only the calling thread?- or all threads of a process?
- some UNIX versions: chosen two versions of
fork()
- if
exec()
called immediately after forking: duplicate only calling thread exec()
: works as normal - replacing the entire process (although only calling thread is copied)- π¨βπ« 'one' of the improvement case
- if
- different improvements exist!
- does
-
Signal handling
- signals: notify a process that a particular event has occurred
- can be receives synchronously / asynchronously
- based on source / reason
- synchronous signals: delivered to same process performing operation causing signal
- d.g. illegal memory access / division by 0
- signals: handled in different ways
- some signals: ignored
- some: handled by terminating program
- e.g. illegal memory access
- signal handler: process signal
- signal: generated by a particular event
- delivered to a process
- handled by one of two signal handlers
- default vs. user defined
- every signal: w/ default handler that kernel users
- where signal shall be delivered for a multi-thread process?
- deliver: signal to thread to signal applies
- deliver: signal to every thread in process
- deliver: signal to certain thread in process
- assign a specific thread to receive all signals
- method of delivering signal: depends on signal type
- synchronous signal: delivered to thread causing the signal (not other threads)
- asynchronous signals (e.g. termination process): sent to all threads
- UNIX function for delivering
kill
signal: send to all thread of the process- s
- specifies
pid
- POSIX Pthread function: allows signal to be delivered to a specified thread
- specifies
tid
- specifies
- d
- signals: notify a process that a particular event has occurred
-
Thread cancellation
-
terminating thread before finishing
- thread to be cancelled: target thread
-
cancellation scenario
- asynchronous cancellation: terminate target thread immediately
- deferred cancellation: target thread: periodically check if it should terminate
- allows termination in orderly fashion
- e.g. when modifying an inter-process variable / in critical point, target thread shouldn't be terminated
-
invoking thread cancellation: requests cancellation
- actual cancellation: depending on thread state / type
-
w/ Pthreads:
-
by nature: cancellation of a thread affects other threads within the same process
mode state type off disabled deferred enabled deferred asynchronous enabled asynchronous Pthread code for created cancel of a thread
#include <pthread.h> #pthread_t tid /* create the thread */ pthread_create(&tid, 0, worker, NULL); // worker: a start routine / function call /* cancel the thread */ pthread_cancel(tid); /* wait for the thread to terminate */ pthread_join(tid, NULL);
-
-
OS example: Windows
- Windows application: runs as a separate process
- Windows API: primary API for Windows app
- w/ one-to-one mapping
- general components of a Window thread
- tid
- register set
- PC
- separate user / kernel stacks
- context of a thread: register set, stacks, and private storage areas
- primary data structures of a thread
- ethread
- kthread
- TEB (thread environment block)
-
OS example: Linux
- Linux: does not differentiate threads & process
- special kind of process: task
- thread in Linux: process that (may) share certain resource w/ other thread
- each thread: w/ unique
task_struct
and appears as a normal process - threads in Linux: happens to share everything (except context)
- e.g. address space
- then they behave like threads
- βπ¨βπ« Linux approach: provides much flexibility
- e.g. sharing program, but not data
- or sharing data, but program
- or sharing file, but nothing else
- impossible with traditional approach
- each thread: w/ unique
- contracts greatly w/ Windows / Sun Solaris
- w/ explicit kernel support for threads / lightweight processes
- if a process: consist of two threads
- in Windows
- in Linux: simply 2 tasks w/ normal
task_struct
structure- that are set up to share resources
- threads: created just like normal tasks
- except:
clone()
syscall used to pass flag clone()
: allows a child task to share part of execution context w/ parentclone()
: specifies what to share- π¨βπ« fork / clone: creates a new task
clone()
: only in Linux
- flags control behavior
- except:
- instead of copying all data structures
- new task points to data structures of parent task
- normal
fork()
: can be implemented asclone(SIGCHLD, 0);
- Linux: does not differentiate threads & process
CPU Scheduling: Basic Concepts
-
Basic concepts
- objective of multiprogramming: have process running at all time
- i.e. maximize CPU utilization
- process execution: made of cycles of CPU execution & IO wait
- ask CPU burst and IO burst
- π¨βπ« based on what you are doing at the point
- when CPU idle:
- OS try to select one process on ready queue & execute
- unless ready queue is empty = no process in ready state
- selection of process: done by CPU scheduler
- aka process scheduler, short-term scheduler
- objective of multiprogramming: have process running at all time
-
History of CPU-burst times
- majority of CPU burst time: very short
- but very few CPU extensive jobs exist
- aka: long-tail distribution
- typically
- d
- distribution: matters when we design a CPU-scheduling algorithm
- majority of CPU burst time: very short
-
CPU scheduler
- CPU scheduler: selects on process thread on ready queue
- i.e. what to be executed next?
- queue
- CPU scheduling: may take place in following 4 conditions (when scheduling must be done)
- switching from running -> waiting state (e.g. IO request / wait)
- process terminates
- giving up CPU voluntarily
- switching from running to ready state
- i.e. interrupt
- switching from waiting to ready / new to ready
- e.g. completion of IO
- new process arrives on ready queue w/ higher priority
- if it is priority-based scheduling
- case 1 & 2: non-preemptive
- giving up CPU voluntarily
- case 3 & 4: preemptive
- OS: forces to give up CPU
- consider access to: shared data
- CPU scheduler: selects on process thread on ready queue
-
Dispatcher
- dispatcher module: allocates CPU to process selected by scheduler
- involves:
- no. of context switches:
- can be obtained by
vmstat
on Linux - ~= hundred context switches / sec usually
- can be obtained by
-
Scheduling criteria
- CPU utilization: fraction of the time that CPU is busy
- as long as ready queue is not empty: CPU must not be idle
- π¨βπ« priority no matter what scheduler you use
- throughput: no. of process / job completed per time
- response time: only matters for robin-round
- fairness
- computation of each: will be explained later
- generally: desirable to optimize all criteria
- but there might be conflict, which different considerations in practice
- mostly
- in practice: we prefer to optimize minimum / maximum values rather than average
- and there are many things to be considered
- π¨βπ« interactive
- interactive: CPU
- non-interactive: does not require sCU attention until termination
- e.g. ML communication
- CPU utilization: fraction of the time that CPU is busy