date: 2024-03-19
title: 04-Threads
status: DONE
tags:
- OS
- NOTE
- Lec4
author:
- AllenYGY
created: 2024-03-20T17:14
updated: 2024-04-08T22:57
publish: True
Threads
A thread is a single sequence stream within a process.
The threads of a process share resources at any given time.
Resources including
code section, data section, OS resources
Most modern applications are multi-threaded
Multiple tasks in an application can be implemented by separate threads
More difficult to program with threads
New categories of bug are possible
Threads vs. Processes
在一个进程中
Processes | Threads |
---|---|
Typically independent | Subsets of a process |
More state information | Share process state and resources |
Separate address spaces | Same address space |
Interact throughIPC models: (shared memory/message passing) | Variables |
Slower context switching | Faster context switching |
Might or might not assist one another | Designed to assist one another |
Multi-core or multi-processor systems putting pressure on programmers
Challenges include:
并发
并行
Identifies performance gains from adding additional cores to an application that has both serial and parallel components
它是用来估计在给定部分程序能够并行化的前提下,多处理器系统相比于单处理器系统在执行该程序时能达到的最大加速比。
串行部分
S
is serial portion, P
is parallel portion of program.S + P = = 1
N
cores: Gustafson's law addresses the shortcomings of Amdahl’s law
It is based on the assumption of a fixed problem size
N,S,P: meanings are same as in Amdahl algorithm.
Gustafson's Law强调了随着问题规模的增加,可以实现更高的并行度
Amdahl's Law则强调了并行计算的理论上限。两者都在并行计算领域提供了重要的视角。
Management[1] done by user-level threads library.
No need for OS support
Works even on very old or very simple OS that does not have system calls for thread management.
No system call required
Fast: only need a library function call.
分配不合理
Management[2] supported by the kernel
Kernel Threads 是处理机分配的单位
Kernel knows how many threads each process contains so it can give more CPU time to the processes with many threads. Kernel更好分配任务
Every thread management operation requires a system call
Slower compared to user-level threads.
Kernel’s PCB data structures more complex
- The kernel needs to keep track of both processes and threads inside processes.
Few systems currently use this model.
Thread library provides programmer with API for creating and managing threads
Library entirely in user space (user threads only)
OS-level library supported by the kernel (user threads mapped to kernel threads, with one-to-one model for example).
May be provided either as user-level or kernel-level
A POSIX standard (IEEE 1003.1c) API for thread creation and synchronization
- Specification, not implementation
- API specifies behavior of the thread library, implementation is up to developers of the library
Common in UNIX operating systems (Linux & Mac OS X)
Implicit threading是一种编程方法,其中并行性是由编译器、运行时系统或其他并行编程框架自动管理的,而不是由程序员显式控制。
Create a number of threads in advance in a pool where they await work
初始化:创建一个线程池,指定线程数量,通常基于可用的CPU核心数。
任务提交:任务提交给线程池,而不是直接提交给某个线程。这些任务通常保持在一个队列中。
任务执行:线程池中的空闲线程从队列中提取任务并执行。一旦线程完成了任务,它就可以用于另一个任务。
优势:这样可以避免为每个任务创建和销毁线程的开销,这种开销可能很大。它还允许更好地控制活跃线程的数量,防止系统因为太多并发线程而过载。
使用场景:线程池被用于服务器应用程序处理多个客户端连接,在工作队列管理中,以及任何任务可能成批出现并需要由限定数量的工作人员处理的情况。
线程池是隐式线程的一种形式,因为程序员不直接管理线程生命周期或任务到线程的分配。相反,他们使用池和任务的更高级别抽象,而底层实现处理线程管理的细节。
Multiple threads (tasks) are forked, and then joined.
- Available in Java. (since Java SE7)
- Similar to Hadoop MapReduce operation
Fork-Join并行模型是一种实现并行处理的编程模式,特别适合于可以递归分解为更小问题的任务。这个模式通常是通过一种显式的方式使用的,但由于其高级的抽象性,它在某些上下文中也可以被看作是隐式线程的一种形式。
Fork-Join模型解释:
在Fork-Join模型中,主要的思想是将一个大的任务分解(Fork)成若干个小任务,这些小任务可以并行处理,处理完毕后再将结果合并(Join)起来。这种模型特别适合处理可以递归分解的问题,比如快速排序、归并排序、图像处理等。
Fork-Join并行模式通常在编程中通过特定的库(如Java中的java.util.concurrent库)来实现,这些库提供了创建任务、同步、以及合并结果的API。程序员需要明确地创建任务,并指定任务之间的分解和合并逻辑。
为什么Fork-Join有时候被看作隐式线程:
虽然Fork-Join模型通常需要程序员明确指定任务的拆分和合并,但是在一些现代编程框架中,如Java的Fork/Join框架,程序员不需要直接管理线程,而是通过高层次的任务(比如RecursiveAction和RecursiveTask)来表达并行逻辑。这些任务被提交到一个可以管理这些任务并自动处理线程分配和同步的线程池。在这个意义上,尽管Fork-Join模型需要程序员做一些并行设计,但线程的具体管理是由框架隐式完成的,所以可以认为这有隐式线程的特征。
Set of compiler directives and an API for C, C++, FORTRAN
Provides support for parallel programming in shared-memory environments
Identifies parallel regions – blocks of code that can run in parallel
OpenMP(Open Multi-Processing)是一个支持多平台共享内存并行编程的应用程序接口(API),其目的是为高性能计算提供一个便捷的方式来编写多线程的应用程序。它定义了一系列编译器指令、运行时库调用和环境变量,这些可以被用来指定高级别的并行性,无需程序员直接管理线程。
主要特点:
跨平台:OpenMP可以在包括UNIX和Windows操作系统在内的多种平台上使用。
简易性:通过编译器指令(通常称为pragma),程序员可以轻松地将串行代码并行化。例如,在C/C++中,一个简单的#pragma omp parallel
就能够将代码块内的指令并行执行。
灵活性:OpenMP允许程序员详细控制线程行为,例如分配和管理数据,以及优化并行执行的性能。
可扩展性:OpenMP可以根据可用的处理器核心数自动调整并行任务的数量。
如何工作:
并行区域:使用#pragma omp parallel
创建并行区域,该区域内的代码将被多个线程并行执行。
循环并行化:对于迭代计算,可以使用#pragma omp for
或#pragma omp parallel for
指令来分配循环迭代给不同的线程。
任务并行化:OpenMP 3.0及以后的版本支持任务并行,允许程序创建可以独立于循环并行化的异步任务。
同步机制:OpenMP提供了多种同步机制,如屏障(#pragma omp barrier
)、临界区(#pragma omp critical
)和原子操作(#pragma omp atomic
),用以控制线程间的执行顺序和数据访问。
数据环境:可以使用#pragma omp
指令的子句来管理数据的作用域(共享或私有)。
OpenMP是一个成熟的API,被广泛应用于科学计算、工程模拟和数据分析等领域。由于它提供了一种高层次的抽象,并能自动处理许多与线程管理相关的复杂性,因此可以认为它在某种程度上提供了隐式线程管理。即使是在并行区域中,大部分的线程管理和同步工作都是自动完成的,使得开发者可以专注于算法的并行化,而不必深入底层的线程管理细节。
Linux declare a TLS variable:
_ _thread int number;
Terminating a thread before it has finished Thread to be canceled is target thread Two general approaches:
Asynchronous cancellation terminates the target thread immediately异步取消会立即终止目标线程
Deferred cancellation allows the target thread to periodically check if it should be cancelled 延迟取消允许目标线程定期检查是否应该取消
Invoking thread cancellation requests cancellation, but actual cancellation depends on thread state
If thread has cancellation disabled, cancellation remains pending until thread enables it
Default type is deferred