首页 > 系统相关 >进程上下文详解

进程上下文详解

时间:2024-05-04 23:33:37浏览次数:27  
标签:执行 任务 详解 线程 切换 进程 上下文 CPU

由于现在大多计算机都是多核CPU,多线程往往会比单线程更快,更能够提高并发,但提高并发并不意味着启动更多的线程来执行。更多的线程意味着线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。

时间片
多任务系统往往需要同时执行多道作业。作业数往往大于机器的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 正在执行的位置,存的值为正在执行的指令的位置或者下一个将要被执行的指令的位置。

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

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

直接消耗:指的是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,又可以减少线程切换的开销。
高并发,低耗时的情况,建议少线程。
低并发,高耗时的情况:建议多线程。
高并发高耗时,要分析任务类型、增加排队、加大线程数

原文链接:https://blog.csdn.net/s_frozen/article/details/127886638

标签:执行,任务,详解,线程,切换,进程,上下文,CPU
From: https://www.cnblogs.com/brucewanglove/p/18172963

相关文章

  • List的remove()方法详解
    https://blog.csdn.net/anxin_hw/article/details/128312846一、错误使用场景1、普通for循环遍历List删除指定元素,list.remove(index)示例:将姓张的名字移除掉List<String>nameList=newArrayList<>(Arrays.asList("张三","李四","王五","赵六"));na......
  • 在Linux中,什么是守护进程,它们是如何工作的?
    在Linux系统中,守护进程(Daemon)是一种特殊的后台进程,它们在用户不直接干预的情况下运行,执行特定的系统任务或等待特定的事件触发。守护进程对于操作系统的稳定运行至关重要,因为它们负责处理许多关键的系统功能。1.守护进程的特点后台运行:守护进程在后台运行,不与任何终端或控制台......
  • 在Linux中,如何查看所有正在运行的进程?
    在Linux中,查看所有正在运行的进程可以使用多种命令,这些命令提供了不同的信息和视图。以下是一些常用的命令:1.ps命令ps(ProcessStatus)是一个基本的进程查看工具,它可以显示当前系统中活动进程的状态。查看所有进程:psauxaux选项组合表示查看所有用户的所有进程。查看特......
  • 在Linux中,如何杀死一个进程?
    在Linux中,你可以使用多种命令来杀死一个进程。下面是一些常用的方法:1.使用kill命令kill命令用于发送信号到进程。默认情况下,kill命令发送TERM信号(即终止信号),它允许进程优雅地关闭。如果进程没有响应TERM信号,你可以使用kill-9来发送KILL信号,这将强制终止进程。示......
  • 【c语言】编译过程详解
    为什么我们编写的C语言要进行编译❓什么是编译❓编译时发生了什么❓机器无法理解我们编写的C语言,而编译就是将面向人类的高级语言转换成为面向机器的机器语言的过程,图1是GCC编译器进行编译的过程,编译时主要分为了4个阶段,每个阶段的具体作用将在接下来进行介绍。图1......
  • iptables使用详解(centos7)
    iptables使用详解(centos7)小百菜已于2024-03-2114:40:02修改阅读量7.2k收藏22点赞数2文章标签:iptables限速版权GitCode开源社区文章已被社区收录加入社区我们需要安装iptables-services,用来启动和停止iptables服务防火墙配置文件/etc/sysconfig/iptables查......
  • execsnoop排查ovs短时进程导致CPU升高
    问题现象节点CPU间隔一段时间后会冲高。通过execsnoop捕捉到在创建网桥(删除网桥捕捉不到,因为删除时不需要确认状态)。#安装execsnoopgitclone--depth1https://github.com/brendangregg/perf-tools./perf-tools/bin/execsnoop#安装ovsyuminstall-yepel-releaseyum......
  • 详解csrf(跨站请求伪造)
    1.什么是csrf(csrf攻击原理)?用户正常访问A网站,A网站设置cookie被用户浏览器保存用户不关闭浏览器,直接访问恶意网站,该恶意网站内隐藏式内嵌了A网站接口的请求链接触发该请求链接,自动携带浏览器保存的cookie,请求成功。2.涉及的基础知识我们先梳理下上面所涉及的一些......
  • 上下文切换
    CPU上下文切换可分为进程上下文切换、线程上下文切换和中断上下文切换。怎么查看系统上下文切换情况vmstat5cs(contextswitch):每秒上下文切换次数。in(interrupt):每秒中断次数。r(RunningorRunnable):就绪队列长度,也就是正在运行和等待CPU的进程数。b(Blocked):处......
  • 高效遍历:C++中分隔字符串单词的3种方法详解与实例
     概述:在C++中,遍历由空格分隔的字符串的单词有多种方法,包括使用`std::istringstream`、手动遍历字符和正则表达式。其中,`std::istringstream`是简单高效的选择,通过流提取单词。手动遍历字符较为繁琐,正则表达式方法更灵活但可能有性能开销。根据实际需求选择方法,本文提供了清晰......