1 多线程概念在理解多线程之前,我们先搞清楚什么是线程。根据维基百科的描述,线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是行程中的实际运行单位。一条线程指的是进程中一个单一顺序的控制流,一個进程中可以并行多个线程,每条线程并行执行不同的任务。每个线程共享堆空间,拥有自己独立的栈空间。 这里反复出现的概念是线程和进程,我们在这里列出它们的区别:
多线程是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,进而提升整体处理效能。 2 为什么要使用多线程随着计算机硬件的发展,多核CPU已经屡见不鲜了,甚至手机处理器都早已是多核的天下。这就给我们使用多线程提供了硬件基础,但是,只是因为硬件让我们可以实现多线程,就要这样做吗?一起来看看多线程的优点:
3 多线程上下文切换的性能损耗前面夸了多线程的优点,凡事都有两面性,使用多线程也有弊端。尽管使用多线程往往可以获得更大的吞吐率和更短的响应时间,但是,多线程程序不一定比单线程程序执行速度快。很多线程存在情况下,线程之间的切换会非常频繁,切换带来的性能损耗是非常可观的。 3.1 上下文切换的概念先来解释一下什么是上下文切换(context switch)。在多任务处理系统中,作业数通常大于CPU数。为了让用户觉得这些任务在同时进行,CPU给每个任务分配一定时间,把当前任务状态保存下来,当前运行任务转为就绪(或者挂起、删除)状态,另一个被选定的就绪任务成为当前任务。之后CPU可以回过头再处理之前被挂起任务。上下文切换就是这样一个过程,它允许CPU记录并恢复各种正在运行程序的状态,使它能够完成切换操作。在这个过程中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运行。 上下文切换在不同的场合有不同的含义,在下表中列出:
根据种类的不同,切换时造成的性能消耗也不同。 究竟什么时候会发生上下文切换?总共有三种情况:
3.2 上下文切换的步骤为了理解为什么上下文切换的时候会损耗性能,我们应该先看看上下文切换的过程中究竟发生了什么。在切换过程中,正在执行的进程的状态必须以某种方式存储起来,这样在未来才能被恢复。这里说的进程状态包括该进程正在使用的所有寄存器(尤其是程序计数器),和一些必要的操作系统数据。保存进程状态的数据结构叫做“进程控制块”(PCB,process control block); PCB通常是系统内存占用区中的一个连续存区,它存放着操作系统用于描述进程情况及控制进程运行所需的全部信息,它使一个在多道程序环境下不能独立运行的程序成为一个能独立运行的基本单位或一个能与其他进程并发执行的进程。 上下文切换的具体步骤是(假设当前进程是进程A,要切换到的下一个进程是进程B):
线程分为用户级线程和内核级线程。同一进程中的用户级线程切换的时候,只需要保存用户寄存器的内容,程序计数器,栈指针,不需要模式切换。但是这样会导致线程阻塞和无法利用多处理器。而同一进程中的内核级线程切换的时候,就克服了这两个缺点,但是除了保存上下文,还要进行模式切换。 线程切换和进程切换的步骤也不同。进程的上下文切换分为两步:1.切换页目录以使用新的地址空间;2.切换内核栈和硬件上下文。对于Linux来说,线程和进程的最大区别就在于地址空间。对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。所以明显是进程切换代价大。线程上下文切换和进程上下文切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。 3.3 上下文切换带来的损耗根据前面的切换步骤,我们可以很容易得到性能损耗的原因。 上下文切换会导致CPU在寄存器和运行队列之间来回奔波。这种消耗可以分为两种
|
|
来自: 纪平aa8woyo5no > 《待分类》