精华内容
下载资源
问答
  • 线程上下文切换

    千次阅读 2018-08-29 10:05:04
    一、为什么要减少线程上下文切换  当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为...

                一、为什么要减少线程上下文切换
                    当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为“上下文切换”(“context switch”)。CPU会在一个上下文中执行一个线程,然后切换到另外一个上下文中执行另外一个线程。上下文切换并不廉价,是比较耗时的
                二、线程上下文切换发生的条件
                    1.中断处理:中断分为硬件中断和软件中断,软件中断包括因为IO阻塞、未抢到资源或者用户代码等原因,线程被挂起
                    2.多任务处理:每个程序都有相应的时间处理片,当前任务的时间片用完之后,系统CPU正常调度下一个任务
                    3.用户状态切换:这种情况下,上下文切换并非一定发生,只在特定操作系统才会发生上下文切换
                三、上下文切换的步骤
                    1.为了理解为什么上下文切换的时候会损耗性能,我们应该先看看上下文切换的过程中究竟发生了什么。在切换过程中,正在执行的进程的状态必须以某种方式存储起来,这样在未来才能被恢复。这里说的进程状态包括该进程正在使用的所有寄存器(尤其是程序计数器),和一些必要的操作系统数据。保存进程状态的数据结构叫做“进程控制块”(PCB,process control block);
                    2.PCB通常是系统内存占用区中的一个连续存区,它存放着操作系统用于描述进程情况及控制进程运行所需的全部信息,它使一个在多道程序环境下不能独立运行的程序成为一个能独立运行的基本单位或一个能与其他进程并发执行的进程。
                    上下文切换的具体步骤是(假设当前进程是进程A,要切换到的下一个进程是进程B):
                        1.保存进程A的状态(寄存器和操作系统数据);
                        2.更新PCB中的信息,对进程A的“运行态”做出相应更改;
                        3.将进程A的PCB放入相关状态的队列;
                        4.将进程B的PCB信息改为“运行态”,并执行进程B;
                        5.B执行完后,从队列中取出进程A的PCB,恢复进程A被切换时的上下文,继续执行A。
                        6.线程分为用户级线程和内核级线程。同一进程中的用户级线程切换的时候,只需要保存用户寄存器的内容,程序计数器,栈指针,不需要模式切换。但是这样会导致线程阻塞和无法利用多处理器。而同一进程中的内核级线程切换的时候,就克服了这两个缺点,但是除了保存上下文,还要进行模式切换。
                    线程切换和进程切换的步骤不同。进程的上下文切换分为两步:1.切换页目录以使用新的地址空间;2.切换内核栈和硬件上下文。对于linux来说,线程和进程的最大区别就在于地址空间。对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。所以明显是进程切换代价大。线程上下文切换和进程上下文切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。
                四、如何减少线程上下文切换
                        1.无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。 
                        2.CAS算法:Java的Atomic包使用CAS(compare and swap)算法来更新数据,而不需要加锁。 
                        3.使用最少线程:避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。 
                        4.协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

    一、上下文切换
        1.即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停的切换线程执行,让我们感觉多个线程是同时执行的,时间片一般是几十毫秒。
        2.CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是在切换之前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。
    二、多线程并不一定快
    三、测试上下文切换的次数和时长
        1.通过Lmbench3测量上下文切换的次数
        2.通过vmstat测量上下文切换的次数
    五、避免死锁的常见方法
        1.避免一个线程同时获取多个锁
        2.避免一个线程在锁内同时占用多个资源
        3.尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
        4.对于数据库锁,加锁和解锁必须在一个数据库连接中,否则会出现解锁失败的情况
    六、资源限制的挑战
        1.什么是资源限制:资源限制是指在进行并发编程的时候,程序的执行速度受限于计算机硬件资源或软件资源。例如:硬件资源限制有带宽的上传和下载速度、硬盘读写速度和CPU的处理速度,软件资源限制有数据库的连接数和socket连接数等
        2.资源限制引起的问题:在并发编程中,将代码执行速度加快的原则是将代码中串行执行的部分变为并发执行,但是如果将某段串行的代码并发执行,因为受限于资源,仍然在串行执行,这个时候系统性能反而会变慢,因为增加了上下文切换和资源调度的时间。
        3.如何解决资源限制的问题:对于硬件资源限制,可以考虑使用资源池将资源服用。
        4.在资源限制下进行并发编程:如何在资源限制的情况下,让程序执行的更快呢?根据不同的资源限制调整程序的并发度。

    展开全文
  • 1.首先,需要搞明白什么是上下文切换上下文切换就是从当前执行任务切换到另一个任务执行的过程。但是,为了确保下次能从正确的位置继续执行,在切换之前,会保存上一个任务的状态。 2. 然后,需要明白进程与线程...

    1.首先,需要搞明白什么是上下文切换?
    上下文切换就是从当前执行任务切换到另一个任务执行的过程。但是,为了确保下次能从正确的位置继续执行,在切换之前,会保存上一个任务的状态。

    2. 然后,需要明白进程与线程的区别?(网上很多,这里简单说明) 
    1).线程是进程的一部分。进程是表示资源分配的基本单位,又是调度运行的基本单位,是程序执行的一个实例; 线程是进程中执行运算的最小单位,即执行处理机调度的基本单位,是进程中的一个执行流。 
    2).内存空间不同。每一个进程拥有自己独立的内存空间,而线程共享进程的内存空间。

    3. 所以,进程上下文切换与线程上下文切换最主要的区别就是线程的切换虚拟空间内存是相同的(因为都是属于自己的进程),但是,进程切换的虚拟空间内存则是不同的。

    同时,这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。

    线程上下文切换比进程上下文切换快的多。

    补充:多线程是如何实现的? 
    主要是CPU通过给每个线程分配CPU时间片来实现多线程的。即使是单核处理器(CPU)也可以执行多线程处理。

    时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程时同时执行的,时间片一般是几十毫秒(ms)。

    4. 在进行上下文切换时,CPU通过时间片分配算法来循环执行任务,Java中的时间片分配算法有哪些? 
    最简单最常用的就是基于时间片轮转调度算法。时间片轮转调度算法是非常公平的处理机分配方式,可以使就绪队列的每个进程每次仅运行一个时间片。 
    原理:在时间片轮转调度算法中,系统根据先来先服务的原则,将所有的就绪进程排成一个就绪队列,并且每隔一段时间产生一次中断,激活系统中的进程调度程序,完成一次处理机调度,把处理机分配给就绪队列队首进程,让其执行指令。当时间片结束或进程执行结束,系统再次将CPU分配给队首进程。

    展开全文
  • 当前线程的CPU时间片使用完,然后处于就绪状态时。 当前线程被其他线程中断时。
    1. 当前线程的CPU时间片使用完,然后处于就绪状态时。
    2. 当前线程被其他线程中断时。
    展开全文
  • 基本功:线程上下文切换

    万次阅读 多人点赞 2019-05-31 22:06:42
    更多的线程意味着线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。可以看另一篇《Java从线程安全到synchronized和Lock探索》 时间片 多任务系统往往需要同时执行多道作业。作业数往往大于...

    由于现在大多计算机都是多核CPU,多线程往往会比单线程更快,更能够提高并发,但提高并发并不意味着启动更多的线程来执行。更多的线程意味着线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。可以看另一篇《Java从线程安全到synchronized和Lock探索

    时间片

    多任务系统往往需要同时执行多道作业。作业数往往大于机器的CPU数,然而一颗CPU同时只能执行一项任务,如何让用户感觉这些任务正在同时进行呢? 操作系统的设计者 巧妙地利用了时间片轮转的方式

    时间片是CPU分配给各个任务(线程)的时间!

    思考:单核CPU为何也支持多线程呢?

    线程上下文是指某一时间点 CPU 寄存器和程序计数器的内容,CPU通过时间片分配算法来循环执行任务(线程),因为时间片非常短,所以CPU通过不停地切换线程执行。

    换言之,单CPU这么频繁,多核CPU一定程度上可以减少上下文切换。

    超线程

    现代CPU除了处理器核心之外还包括寄存器、L1L2缓存这些存储设备、浮点运算单元、整数运算单元等一些辅助运算设备以及内部总线等。一个多核的CPU也就是一个CPU上有多个处理器核心,就意味着程序的不同线程需要经常在CPU之间的外部总线上通信,同时还要处理不同CPU之间不同缓存导致数据不一致的问题。

    超线程这个概念是Intel提出的,简单来说是在一个CPU上真正的并发两个线程,由于CPU都是分时的(如果两个线程A和B,A正在使用处理器核心,B正在使用缓存或者其他设备,那AB两个线程就可以并发执行,但是如果AB都在访问同一个设备,那就只能等前一个线程执行完后一个线程才能执行)。实现这种并发的原理是 在CPU里加了一个协调辅助核心,根据Intel提供的数据,这样一个设备会使得设备面积增大5%,但是性能提高15%~30%。

    上下文切换

    • 线程切换,同一进程中的两个线程之间的切换
    • 进程切换,两个进程之间的切换
    • 模式切换,在给定线程中,用户模式和内核模式的切换
    • 地址空间切换,将虚拟内存切换到物理内存

    CPU切换前把当前任务的状态保存下来,以便下次切换回这个任务时可以再次加载这个任务的状态,然后加载下一任务的状态并执行。任务的状态保存及再加载, 这段过程就叫做上下文切换。

    每个线程都有一个程序计数器(记录要执行的下一条指令),一组寄存器(保存当前线程的工作变量),堆栈(记录执行历史,其中每一帧保存了一个已经调用但未返回的过程)。

    寄存器 是 CPU 内部的数量较少但是速度很快的内存(与之对应的是 CPU 外部相对较慢的 RAM 主内存)。寄存器通过对常用值(通常是运算的中间值)的快速访问来提高计算机程序运行的速度。

    程序计数器是一个专用的寄存器,用于表明指令序列中 CPU 正在执行的位置,存的值为正在执行的指令的位置或者下一个将要被执行的指令的位置。

    1. 挂起当前任务(线程/进程),将这个任务在 CPU 中的状态(上下文)存储于内存中的某处
    2. 恢复一个任务(线程/进程),在内存中检索下一个任务的上下文并将其在 CPU 的寄存器中恢复
    3. 跳转到程序计数器所指向的位置(即跳转到任务被中断时的代码行),以恢复该进程在程序中

    线程上下文切换会有什么问题呢?

    上下文切换会导致额外的开销,常常表现为高并发执行时速度会慢串行,因此减少上下文切换次数便可以提高多线程程序的运行效率。

    • 直接消耗:指的是CPU寄存器需要保存和加载, 系统调度器的代码需要执行, TLB实例需要重新加载, CPU 的pipeline需要刷掉
    • 间接消耗:指的是多核的cache之间得共享数据, 间接消耗对于程序的影响要看线程工作区操作数据的大小

    切换查看

    Linux系统下可以使用vmstat命令来查看上下文切换的次数, 其中cs列就是指上下文切换的数目一般情况下, 空闲系统的上下文切换每秒大概在1500以下

    线程调度

    抢占式调度

    指的是每条线程执行的时间、线程的切换都由系统控制,系统控制指的是在系统某种运行机制下,可能每条线程都分同样的执行时间片,也可能是某些线程执行的时间片较长,甚至某些线程得不到执行的时间片。在这种机制下,一个线程的堵塞不会导致整个进程堵塞。

    java使用的线程调使用抢占式调度,Java中线程会按优先级分配CPU时间片运行,且优先级越高越优先执行,但优先级高并不代表能独自占用执行时间片,可能是优先级高得到越多的执行时间片,反之,优先级低的分到的执行时间少但不会分配不到执行时间。

    协同式调度

    指某一线程执行完后主动通知系统切换到另一线程上执行,这种模式就像接力赛一样,一个人跑完自己的路程就把接力棒交接给下一个人,下个人继续往下跑。线程的执行时间由线程本身控制,线程切换可以预知,不存在多线程同步问题,但它有一个致命弱点:如果一个线程编写有问题,运行到一半就一直堵塞,那么可能导致整个系统崩溃。

    线程让出cpu的情况

    • 当前运行线程主动放弃CPU,JVM暂时放弃CPU操作(基于时间片轮转调度的JVM操作系统不会让线程永久放弃CPU,或者说放弃本次时间片的执行权),例如调用yield()方法。
    • 当前运行线程因为某些原因进入阻塞状态,例如阻塞在I/O上
    • 当前运行线程结束,即运行完run()方法里面的任务

    引起线程上下文切换的因素

    • 当前执行任务(线程)的时间片用完之后,系统CPU正常调度下一个任务
    • 中断处理,在中断处理中,其他程序”打断”了当前正在运行的程序。当CPU接收到中断请求时,会在正在运行的程序和发起中断请求的程序之间进行一次上下文切换。中断分为硬件中断和软件中断,软件中断包括因为IO阻塞、未抢到资源或者用户代码等原因,线程被挂起。
    • 用户态切换,对于一些操作系统,当进行用户态切换时也会进行一次上下文切换,虽然这不是必须的。
    • 多个任务抢占锁资源,在多任务处理中,CPU会在不同程序之间来回切换,每个程序都有相应的处理时间片,CPU在两个时间片的间隔中进行上下文切换

    因此优化手段有:

    • 无锁并发编程,多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash取模分段,不同的线程处理不同段的数据
    • CAS算法,Java的Atomic包使用CAS算法来更新数据,而不需要加锁
    • 使用最少线程
    • 协程,单线程里实现多任务的调度,并在单线程里维持多个任务间的切换

    合理设置线程数目既可以最大化利用CPU,又可以减少线程切换的开销。

    • 高并发,低耗时的情况,建议少线程。
    • 低并发,高耗时的情况:建议多线程。
    • 高并发高耗时,要分析任务类型、增加排队、加大线程数
    展开全文
  • 1、首先,需要搞明白什么是上下文切换?(面试题) 上下文切换就是从当前执行任务切换到另一个任务执行的过程。但是,为了确保下次能从正确的位置继续执行,在切换之前,会保存上一个任务的状态。 2、 然后,需要...
  • 虽然并不是真正意义的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行。 再后来发展到多线程技术,使得在一个程序...
  • 进程上下文切换与线程上下文切换

    千次阅读 2020-04-06 22:45:33
    进程上下文切换 进程上下文包含了进程执行所需要的所有信息。 用户地址空间:包括程序代码,数据,用户堆栈等; 控制信息:进程描述符,内核栈等;...线程上下文切换 对于linux来说,线程和进程的最大...
  • 进程、线程上下文切换

    千次阅读 2020-05-24 22:12:02
    上下文切换(有时也称做进程切换或任务切换)是指 CPU 从一个进程或线程切换到另一个进程或线程上下文切换可以认为是内核(操作系统的核心)在 CPU 上对于进程(包括线程)进行以下的活动:(1)挂起一个进程,将...
  • 进程、线程上下文切换的开销

    千次阅读 2020-09-10 11:21:07
    进程、线程上下文切换的开销 虚拟内存与地址空间映射关系 虚拟内存是操作系统为每个进程提供的一种抽象,每个进程都有属于自己的、私有的、地址连续的虚拟内存,当然我们知道最终进程的数据及代码必然要放到物理...
  • 首先,需要搞明白什么是上下文切换上下文切换就是从当前执行任务切换到另一个任务执行的过程。但是,为了确保下次能从正确的位置继续执行,在切换之前,会保存上一个任务的状态。 然后,需要明白进程与线程的...
  • 线程上下文切换详解

    万次阅读 多人点赞 2019-05-30 14:35:17
    什么是上下文切换? CPU通过分配时间片来执行任务,当一个任务的时间片用完,就会切换到另一个任务。在切换之前会保存上一个任务的状态,当下次再切换到该任务,就会加载这个状态。 ——任务从保存到再加载的过程...
  • 通过上一讲的讲解,相信你对上下文切换已经有了一定的了解了。如果是单个线程,在 CPU 调用之后,那么它基本上是不会被调度出去的。如果可运行的线程数远大于 CPU 数量,那...
  • 线程数量设置太大,可能带来资源的过度竞争,导致上下文切换,带来的额外的系统开销 上下文切换 1.在单处理器时期,操作系统就能处理多线程并发任务,处理器给每个线程分配CPU时间片,线程在CPU时间片内执行任务...
  • CPU 上下文切换 多任务操作系统中,多于CPU个数的任务同时运行就需要进行任务调度,从而多个任务轮流使用CPU。 从用户角度看好像所有的任务同时在运行,实际上是多个任务你运行一会,我运行一会,任务切换的速度很快...
  • 如何减少线程上下文切换

    千次阅读 2019-04-15 22:35:18
    频繁的线程上下文切换会成为一个系统瓶颈,本来引入线程就是为了提高系统运行效率,这下倒好了,频繁的线程上下文切换可能会给系统造成更大的系统开销,让系统苦不堪言。 首先了解一下,线程切换似乎有两种方式,第...
  • Rust异步和Linux线程上下文切换时间和内存使用情况的比较 这是一些试图以各种方式衡量上下文切换时间和任务内存使用情况的程序。 总之: 异步任务之间的上下文切换大约需要0.2µs,而内核线程之间的切换大约需要1.7...
  • 引起上下文切换的原因引起上下文切换的原因如下 引起上下文切换的原因如下 当前正在执行的任务完成,系统的cpu正常调度下一个任务 当前正在执行的任务遇到i/o等阻塞操作,调度器挂起此任务,继续调度下一个任务。 ...
  • 进程是操作系统的伟大发明之一,对应用程序屏蔽了CPU调度、内存管理等硬件细节,而抽象出一个进程的概念,让应用程序专心于实现自己的业务逻辑既可,而且在有限的CPU可以“同时”进行许多个任务。但是它为用户带来...
  • 进程切换分两步 1.切换页目录以使用新的地址空间 ...线程上下文切换和进程上下问切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通
  • 什么是上下文切换 即使是单核CPU也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程...
  • 查询线程上下文切换次数

    千次阅读 2019-06-05 15:14:39
    CS content switch表示上下文切换的次数
  • 线程上下文切换的性能损耗测试

    千次阅读 2015-12-04 13:06:07
    线程上下文切换的性能损耗测试
  • 在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临非常多的挑战,比如上下文切换的问题、死锁的问题,以及受限于硬件和软件的资源限制问题,本文要研究的是上下文切换的问题。 什么是上下文...
  • 点击上方“码农进阶之路”,选择“设为星标”回复“面经”获取面试资料什么是vmstat概念:vmstat测量上下文切换的次数,vmstat命令是最常见的Linux/Unix监控工具,可以展...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 127,430
精华内容 50,972
关键字:

线程上下文切换