关于进程:进程最后的遗言

过程最初的遗嘱前言在本篇文章当中次要给大家介绍父子过程之间的关系,以及他们之间的交互以及可能造成的状态,帮忙大家深刻了解父子过程之间的关系,以及他们之间的交互。 僵尸过程和孤儿过程僵尸过程在 Unix 操作系统和类 Unix 操作系统当中,当子过程退出的时候,父过程能够从子过程当中获取子过程的退出信息,因而在 类 Unix 操作系统当中只有父过程通过 wait 零碎调用读取子过程的退出状态信息之后,子过程才会齐全退出。那么子过程在程序执行实现之后(调用 _exit 零碎调用之后),到父过程执行 wait 零碎调用获取子过程退出状态信息之前,这一段时间的过程的状态是僵尸过程的状态。 正式定义:在 Unix 或者类 Unix 操作系统当中,僵尸过程就是哪些曾经实现程序的执行(实现_exit 零碎调用退出了程序),然而在内核当中还有属于这个过程的过程表项。这个表项的作用次要是让父过程读取子过程的退出状态信息 (exit status)。 在后文当中咱们有一个例子详细分析这个退出状态的相干信息。一旦父过程通过 wait 零碎调用读取完子过程的 exit statis 信息之后,僵尸过程的过程表项就会从过程表(process table)当中被移除,这个过程就算是彻底沦亡了(reaped)。 如果零碎当中有很多处于僵尸状态的过程而父过程又没有应用 wait 零碎调用去失去子过程的退出状态,那么零碎当中就会有很多内存没有被开释,这就会导致资源泄露。 上面是一个僵尸过程的例子,对应的代码名称为 Z.c: #include <stdio.h>#include <unistd.h>int main() { printf("parent pid = %d\n", getpid()); if(fork()) { while(1); } printf("child process pid = %d\n", getpid()); return 0;}下面C语言对应的python代码如下: import osif __name__ == "__main__": print(f"parent pid = {os.getpid()}") pid = os.fork() if pid != 0: # parent process will never exit while True: pass # child process will exit print(f"child process pid = {os.getpid()}")当初执行下面的程序,失去的后果如下所示: ...

October 28, 2022 · 4 min · jiezi

关于进程:用闪电侠解释一下进程和线程

1.艾伦在一次粒子加速器爆炸大事变中取得了极速挪动的超能力,因而开始化身为超级英雄“闪电侠”。类比之下,CPU是计算机最外围的部件,它负责指令的读取和执行,每秒能够执行几十亿条指令!其实比闪电侠还要快得多。 小闪这种能力很快就被FBI发现了,为了好好利用小闪,FBI雇佣了小闪为其特地口头小组A执行工作。 说是特地口头小组,其实除了小闪之外只有一个A博士,小闪日常的工作就是获得A博士的指令并且执行。这就是计算机晚期的单过程模型。 2. 然而A博士从搜集情报到得出正确的指令毕竟须要工夫,而小闪执行指令的速度又太快,所以在FBI高层眼里,A博士总是忙忙碌碌,而小闪成天优哉游哉。 为了进步小闪的利用率,FBI在特地口头小组办公室的楼下,着手成立另一个特地口头小组B。 这个着手成立的过程就是编码,而编码的后果就是失去一个可能实现某个特定性能的程序。很快,特地口头小组B在B博士的单独主持下开始暗中运行。这就是过程的诞生,过程其实就是运行的程序。当初FBI特地口头小组进入了多过程时代。 3.尽管都是FBI的特地口头小组,若无非凡状况,A和B通常井水不犯河水,他们都认为本人垄断了FBI的所有资源,但这其实只是FBI的小把戏而已。 背地的含意就是每个过程采纳了完全相同的虚拟地址空间,然而经由操作系统和硬件MMU合作,映射到不同的物理地址空间。 不同的过程,都有各自独立的物理内存空间,特地口头小组A和B之间的通信就是过程间通信(IPC)。 4.小闪尽管速度快,然而仍然没方法在同一时刻同时执行A博士和B博士两个人的指令,就如同人不能在向右看的同时向左看。 A博士和B博士经常为此大打出手,谁都想占用小闪更多的工夫,好实现本人的KPI。 FBI领导层想了一个方法,新成立了一个调度小组,用来给各个小组调配小闪的应用工夫。一开始,调度小组会给每个过程调配相等的一小段时间,而后每个小组轮流地占用小闪执行相应工夫的工作。这就是CPU的工夫片调配。 如果小闪在这一小段时间内还没执行完,那也必须得停,然而得保留一下执行进度,下次持续从完结的中央开始做。这就是CPU的上下文切换。 这样一来,A博士和B博士的KPI实现了,小闪也忙起来了。说是忙起来,然而花在指令执行上的工夫其实也没多多少,根本就是在两个小组之间重复横跳了,小闪的工作仍然惬意。 5.两个博士眼红于小闪仍然有大把的闲暇工夫,竟然颇有默契地发动了招聘布告,广揽天下英才,势必要多找点事件给小闪做。 很快,口头小组内的成员越来越多,并且每个成员的工作都不一样,比方有些人负责查阅材料,有些人负责收取讯息......小组内各个成员分工协作,实现特地小组的独特指标。自此进入多线程时代。 线程就好比是小组内的成员,一个过程能够蕴含很多个线程。 过程是资源分配的根本单位,比方FBI给特地小组调配办公场合。 线程是CPU调度的根本单位,比方小闪须要执行每个小组成员的指令。 6. 成员多了,治理就成了一个新的问题。如果每个成员只是自说自话,齐全不考究团队合作,极容易造成团队外部抵触。 为此,FBI制订了几个策略。对应的是线程的同步。 7. 口头小组内的资源不同,共享的水平也不一样。比方厕所,当有人正在应用的时候,其他人只能期待,如果贸然闯进去必然呈现抵触。这示意过程中的某些共享内存同一时间只能由一个线程应用,其余线程必须期待该线程完结应用之后能力持续应用。 一个避免其他人进入的简略办法就是给厕所增加一把锁,首先占用厕所的人上锁,其他人看到有锁之后就在门口排队,直到占用的线程开释锁能力进入。这个策略叫做「互斥锁」,英文叫做Mutex。 8. 不同于厕所,会议室就能同时容许10集体进入,如果人数超过10个,多进去的人只能排队等着,除非有人空出地位,其他人能力进入会议室。 为了解决这个问题,FBI在会议室的门口挂了10把钥匙,每个人进入会议室前都要取一把钥匙,进去时把钥匙放回原位。如果后来者发现没有钥匙了,就在会议室门口期待。这种策略叫做「信号量」,互斥锁只容许一个线程进入临界区,信号量容许多个线程同时进入临界区。 9. 有些时候,口头小组的某些工作比较复杂,须要流水线式作业。上游的人员做完之后把后果交付给上游人员解决,这就是典型的生产者消费者模式。 如果生产者生产得太快,咱们能够适当让上游的人员进行作业,期待某个机会唤醒生产者;反之,如果消费者生产得太快,咱们能够适当让上游的人员进行作业,等到某个机会唤醒消费者。 这种策略叫做「条件变量」,背地的原理是当线程在期待某些条件时使线程进入睡眠状态,一旦条件满足,就唤醒。 10. 最初拿口头小组的放映机举个例子。很多成员喜爱在休息时间坐在一起应用放映机看个电影,消遣一下工夫,相似于多线程对同一资源进行读操作,这种状况下不论多少人在看电影都不会呈现问题。 然而偏偏有人在其他人看电影的时候要降级一下放映机的操作系统,这必定会影响其他人的观影体验;反之,在降级操作系统的时候,有人要看电影,这同样会对降级人员造成困扰。 这种时候咱们能够定一个策略,当观影时,随时欢迎其余观影人员应用观看;当降级时,禁止任何观影人员和任何其余降级人员应用。 这种形式称为「读写锁」,也叫做「共享-独占锁」,“观影”对应的就是线程的读操作,“降级”对应的就是线程的写操作。具体来说个别有两种状况: 读写锁处于写锁定的状态,则在解锁之前,所有试图加锁的线程都会阻塞;读写锁处于读锁定的状态,则所有试图以读模式加锁的线程都可失去拜访权,然而以写模式加锁的线程则会阻塞;作者:蝉沐风公众号:蝉沐风欢送我,邂逅更多精彩文章完!

August 5, 2022 · 1 min · jiezi

关于进程:每日一篇730进程调度算法

调度算法的意义程序运行时,通常会有多个过程或线程同时竞争CPU,然而如果只有一个CPU可用,那就必须抉择下一个要运行的过程。在操作系统中实现抉择工作的一部分叫做调度程序。然而过程也有辨别,CPU密集型:大多工夫在计算IO密集型:大多工夫在IO期待切换(因为当初CPU的性能进步 ,次要是IO密集型)调度算法的目标就是为了放弃零碎所有局部尽可能繁忙。次要有四个指标掂量调度算法的好坏,吞吐量、周转工夫、CPU利用率、响应工夫。并且调度程序须要思考到CPU利用率,因为过程的切换比拟高,用户态必须切换到内核态,而后保留以后过程的状态,包含在过程表中存储寄存器值以便当前从新装载。调度算法分类:批处理、交互式、实时 批处理零碎的调度先来先服务First-come first-served,依照过程申请的程序应用CPU。相当于有一个就绪过程的繁多队列。长处:易于了解便于在程序中使用。毛病:如果某个过程过大,会导致前面过程饥饿。 短作业优先:毛病:对长过程不敌对。 最短剩余时间优先是短作业优先的抢占式版本,总是抉择残余运行工夫最短的那个过程运行,须要对整个事件同以后过程的剩余时间比拟,如果右小于以后过程的,以后过程就会被挂起,运行新的过程。 交互式零碎的调度轮转调度每个过程都会被分一个时间段,即工夫片,容许该过程在该工夫片内运行。调度程序须要保护一张可运行过程列表。:毛病:工夫片设置的过长会导致短的交互申请的响应工夫变长,过短会导致过多过程切换升高CPU效率。 优先级调度优先级能够是动态赋予也能够是动静赋予。比方将优先级设为该过程在上一时间片所占局部的倒数。毛病:可能会导致低优先级过程产生饥饿景象。须要偶然堆优先级进行调整。 彩票调度实时零碎的调度实时零碎是工夫起主导作用的零碎。 硬实时即必须满足相对的截止工夫。将程序划分为一组过程实现,每个过程的行为都是能够预测和提前把握的。 软实时

July 31, 2022 · 1 min · jiezi

关于进程:一道进程相关面试题引发的思考

“ 小明同学最近贼郁闷,去年玩比特币亏得一塌糊涂,想在股市里翻盘,听信大V举荐的股票,买了康美和长生生物,被A股狠狠的收割了一把。本想往年好好工作,谁晓得遇上了O记大裁员。尽管拿了N+6,然而还是要找工作养家糊口啊!只能硬着头皮去面试了,还好,面试题目都不难,因为小明认真看过《奔跑吧》” 01 面试题目 在一个双核处理器的零碎中,在shell界面下运行test程序。CPU0的就绪队列上有4个过程,而CPU1的就绪队列有1个过程。假如test程序和这个5个过程的nice值都是为0。 test程序 执行test过程 问题: 请画出test程序在内核空间的执行流程图。若干工夫之后,CPU0和CPU1的就绪队列变动如何?小明听到这题目,嘿嘿一笑,so easy,难不到窝,这题目比炒A股简略多了!于是在黑板上开始边写边画,缄口结舌。 02 题目解析 站在用户空间的角度看,在shell界面下执行test程序,shell程序会调用fork零碎调用来创立一个新过程,而后调用exec零碎调用来装载test过程,因而新过程便开始执行test程序。 站在用户空间的角度看问题,咱们只能看到test程序被执行了,然而咱们是看不到新过程是如何被创立的,它会增加到哪个CPU里,它是如何执行的,以及CPU0和CPU1之间如何做负载平衡等等问题。 小明画的test过程执行流程图 从上图可知,咱们把test过程在内核空间的执行过程分成了6个步骤。 (1)调用零碎调用fork零碎调用来创立一个新过程 (2)do_fork()创立新过程。do_fork要做好多事件,比方: a)创立新过程过程管制块PCB,task_struct数据结构。 b)拷贝父过程的task_struct数据结构内容到新过程。 c)拷贝父过程的页表项内容到新过程。 d)设置新过程的内核栈 (3)父过程调用wake_up_new_task()尝试去唤醒新过程。 a)调用调度类的select_task_rq()办法,为新过程寻找一个负载最轻的CPU,这里抉择CPU1。 b)调用调度类的enqueue_task()办法把新过程增加到CPU1的就绪队列里。 (4)CPU1从新抉择一个适合的过程来运行。 a)每次时钟滴答到来时,scheduler_tick()会调用调度类的task_tick()去查看是否须要从新调度。check_preempt_tick()查看是否须要从新调度。若须要调度,则设置以后过程的thread_info中的TIF_NEED_RESCHED标记位。假如在咱们这个场景里,CPU1筹备调度咱们的新过程P,那么就会设置以后过程curr的thread_info中的TIF_NEED_RESCHED标记位。 b)在中断返回前会查看以后过程curr的TIF_NEED_RESCHED标记位。如果须要调度的话,调用preempt_schedule_irq()来切换过程运行。 c)调度器的schedule()函数会调用调度类的pick_next_task()办法来抉择下一个最合适运行的过程。在咱们的场景中,抉择新过程P。 d)switch_mm()切换prev过程和新过程的页表。 e)在CPU1上,switch_to()切换新过程P来执行。 (5)新过程执行。 a)新过程的第一次执行会调用ret_from_fork()函数。 b)返回用户空间执行shell程序。 c)shell程序调用exec()零碎调用来执行test程序,最终新过程变成了test过程。 (6)负载平衡。 a)在每次时钟滴答到来时去查看是否须要触发软中断来做SMP负载平衡。scheduler_tick()->trigger_load_balance()。下一次做负载平衡的工夫点寄存在就绪队列的next_balance成员里。 b)触发SCHED_SOFTIRQ软中断。 c)在软中断处理函数run_rebalance_domains()里,从以后CPU开始遍历CPU拓扑关系图,从调度域的低层往高层遍历调度域,并寻找有负载不平均的调度组。本例子中的CPU拓扑关系图很简略,只有一层MC级别的调度域。 d)CPU0对应的调度域是domain_mc_0,对应的调度组是group_mc_0;CPU1对应的调度域是domain_mc_1,对应的调度组是group_mc_1。CPU0的调度域domain_mc_0管辖CPU0和CPU1,其中group_mc_0和group_mc_1这两个调度组会连贯到domain_mc_0的一个链表里,同理CPU1的调度域domain_mc_1也是同样治理着group_mc_1和group_mc_0这两个调度组。 e)假如以后运行的CPU是CPU1,也就是说运行到run_rebalance_domains()函数的CPU为CPU1,那么在以后MC的调度域(domain_mc_1)里去找哪个调度组是最忙碌的。在咱们的场景里,很容易找到CPU0的那个调度组(group_mc_0)是最忙碌的。计算须要迁徙多少的负载量到CPU1上能力放弃两个调度组负载平衡。 f)迁徙过程从CPU0到CPU1。 g)达到新的均衡。 笨叔点评: 这是一道很棒的面试题目,把过程方方面面的问题都考到了,比如说过程的创立,过程的调度,过程的执行,SMP负载平衡。外面任何的一点,都足以难倒很多人,比如说: 过程的实质是什么? 过程的调度实质是什么? 调度器怎么抉择下一个过程? 处理器是怎么就切换和执行到下一个过程? CFS调度器和过程优先级到底有什么关系? CFS调度器里的虚构时钟是个什么鬼? runnable和running是啥关系? 什么是过程的权重? 什么是过程的负载? 调度域和调度组是个什么鬼? 如何能疾速画出一个零碎的CPU拓扑关系图? SMP负载平衡里是怎么掂量一个就绪队列的负载的? SMP负载平衡算法是怎么玩的? 负载和权重到底有什么关系? Linux的负载平衡算法里说的负载是怎么计算的? 怎么了解衰减(decay)? ... 笨叔正在批改蓝色版本的《奔跑吧》,基于Linux 5.0+ARM64,欢送大家提意见和idea!好的idea,笨叔好酒相赠! 更多精彩内容,关注笨叔的微信公众号以及笨叔免费旗舰篇视频。 ...

April 2, 2022 · 1 min · jiezi

关于进程:图文介绍进程和线程的区别

过程和线程的概念 先理解一下操作系统的一些相干概念,大部分操作系统(如Windows、Linux)的任务调度是采纳工夫片轮转的抢占式调度形式,也就是说一个工作执行一小段时间后强制暂停去执行下一个工作,每个工作轮流执行。工作执行的一小段时间叫做工夫片,工作正在执行时的状态叫运行状态,工作执行一段时间后强制暂停去执行下一个工作,被暂停的工作就处于就绪状态期待下一个属于它的工夫片的到来。这样每个工作都能失去执行,因为CPU的执行效率十分高,工夫片十分短,在各个工作之间疾速地切换,给人的感觉就是多个工作在“同时进行”,这也就是咱们所说的并发(并发简略来说多个工作同时执行)。过程 计算机的外围是CPU,它承当了所有的计算工作;而操作系统是计算机的管理者,它负责工作的调度、资源的调配和治理,统领整个计算机硬件;应用程序侧是具备某种性能的程序,程序是运行于操作系统之上的。 过程是一个具备肯定独立性能的程序在一个数据集上的一次动静执行的过程,是操作系统进行资源分配和调度的一个独立单位,是利用程序运行的载体。过程是一种形象的概念,素来没有对立的规范定义。过程个别由程序、数据汇合和过程管制块三局部组成。程序用于形容过程要实现的性能,是管制过程执行的指令集;数据汇合是程序在执行时所须要的数据和工作区;程序控制块(Program Control Block,简称PCB),蕴含过程的形容信息和管制信息,是过程存在的惟一标记。 过程具备的特色: 动态性:过程是程序的一次执行过程,是长期的,有生命期的,是动静产生,动静沦亡的; 并发性:任何过程都能够同其余过程一起并发执行; 独立性:过程是零碎进行资源分配和调度的一个独立单位; 结构性:过程由程序、数据和过程管制块三局部组成。 过程的生命周期 在晚期只有过程的操作系统中,过程有五种状态,创立、就绪、运行、阻塞(期待)、退出。创立:过程正在创立,还不能运行。操作系统在创立过程时要进行的工作包含调配和建设过程管制块表项、建设资源表格并分配资源、加载程序并建设地址空间; 就绪:工夫片已用完,此线程被强制暂停,期待下一个属于他的工夫片到来; 运行:此线程正在执行,正在占用工夫片; 阻塞:也叫期待状态,期待某一事件(如IO或另一个线程)执行完; 退出:过程已完结,所以也称完结状态,开释操作系统调配的资源。 线程 在晚期的操作系统中并没有线程的概念,过程是能领有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采纳的是工夫片轮转的抢占式调度形式,而过程是任务调度的最小单位,每个过程有各自独立的一块内存,使得各个过程之间内存地址互相隔离。 起初,随着计算机的倒退,对CPU的要求越来越高,过程之间的切换开销较大,曾经无奈满足越来越简单的程序的要求了。于是就创造了线程,线程是程序执行中一个繁多的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的根本单位。一个过程能够有一个或多个线程,各个线程之间共享程序的内存空间。 一个规范的线程由线程ID、以后指令指针(PC)、寄存器和堆栈组成。而过程由内存空间(代码、数据、过程空间、关上的文件)和一个或多个线程组成。 线程的生命周期 当线程的数量小于处理器的数量时,线程的并发是真正的并发,不同的线程运行在不同的处理器上。但当线程的数量大于处理器的数量时,线程的并发会受到一些妨碍,此时并不是真正的并发,因为此时至多有一个处理器会运行多个线程。在单个处理器运行多个线程时,并发是一种模仿进去的状态。操作系统采纳工夫片轮转的形式轮流执行每一个线程。当初,简直所有的古代操作系统采纳的都是工夫片轮转的抢占式调度形式,如咱们相熟的Unix、linux、Windows及Mac OS X等风行的操作系统。创立:一个新的线程被创立,期待该线程被调用执行; 就绪:工夫片已用完,此线程被强制暂停,期待下一个属于他的工夫片到来; 运行:此线程正在执行,正在占用工夫片; 阻塞:也叫期待状态,期待某一事件(如IO或另一个线程)执行完; 退出:一个线程实现工作或者其余终止条件产生,该线程终止进入退出状态,退出状态开释该线程所调配的资源。 线程优先级 操作系统(如Windows、Linux、Mac OS X)的任务调度除了具备后面提到的工夫片轮转的特点外,还有优先级调度(Priority Schedule)的特点。优先级调度决定了线程依照什么程序轮流执行,在具备优先级调度的零碎中,线程领有各自的线程优先级(Thread Priority)。具备高优先级的线程会更早地执行,而低优先级的线程通常要等没有更高优先级的可执行线程时才会被执行。 线程的优先级能够由用户手动设置,此外零碎也会依据不同情景调整优先级。通常状况下,频繁地进入期待状态(进入期待状态会放弃之前仍可占用的工夫份额)的线程(如IO线程),比频繁进行大量计算以至于每次都把所有工夫片全副用尽的线程更受操作系统的欢送。因为频繁进入期待的线程只会占用很少的工夫,这样操作系统能够解决更多的工作。咱们把频繁期待的线程称之为IO密集型线程(IO Bound Thread),而把很少期待的线程称之为CPU密集型线程(CPU Bound Thread)。IO密集型线程总是比CPU密集型线程更容易失去优先级的晋升。 线程饿死 在优先级调度下,容易呈现一种线程饿死的景象。一个线程饿死是说它的优先级较低,在它执行之前总是有比它优先级更高的线程期待执行,因而这个低优先级的线程始终得不到执行。当CPU密集型的线程优先级较高时,其它低优先级的线程就很可能呈现饿死的状况;当IO密集型线程优先级较高时,其它线程绝对不容易造成饿死的,因为IO线程有大量的等待时间。为了防止线程饿死,调度零碎通常会逐渐晋升那些期待了很久而得不到执行的线程的优先级。这样,一个线程只有它期待了足够长的工夫,其优先级总会被晋升到能够让它执行的水平,也就是说这种状况下线程始终会失去执行,只是工夫的问题。 在优先级调度环境下,线程优先级的扭转有三种形式: 1.用户指定优先级; 2.依据进入期待状态的频繁水平晋升或升高优先级(由操作系统实现); 3.长时间得不到执行而被晋升优先级。 多线程与多核 下面提到的工夫片轮转的调度形式说一个工作执行一小段时间后强制暂停去执行下一个工作,每个工作轮流执行。很多操作系统的书都说“同一时间点只有一个工作在执行”。其实“同一时间点只有一个工作在执行”这句话是不精确的,至多它是不全面的。咱们剖析一下多核的状况。 这是我的电脑的CPU状况图:多核(心)处理器是指在一个处理器上集成多个运算外围从而进步计算能力,也就是有多个真正并行计算的解决外围,每一个解决外围对应一个内核线程。内核线程(Kernel Thread, KLT)就是间接由操作系统内核反对的线程,这种线程由内核来实现线程切换,内核通过操作调度器对线程进行调度,并负责将线程的工作映射到各个处理器上。个别一个解决外围对应一个内核线程,比方单核处理器对应一个内核线程,双核处理器对应两个内核线程,四核处理器对应四个内核线程。 当初的电脑个别是双核四线程、四核八线程,是采纳超线程技术将一个物理解决外围模仿成两个逻辑解决外围,对应两个内核线程,所以在操作系统中看到的CPU数量是理论物理CPU数量的两倍。然而我的如上图是四核四线程,仿佛没有用这个超线程技术。 超线程技术就是利用非凡的硬件指令,把一个物理芯片模仿成两个逻辑解决外围,让单个处理器都能应用线程级并行计算,进而兼容多线程操作系统和软件,缩小了CPU的闲置工夫,进步的CPU的运行效率。这种超线程技术(如双核四线程)由处理器硬件的决定,同时也须要操作系统的反对能力在计算机中体现进去。 程序个别不会间接去应用内核线程,而是去应用内核线程的一种高级接口——轻量级过程(Light Weight Process,LWP),轻量级过程就是咱们通常意义上所讲的线程(咱们在这称它为用户线程),因为每个轻量级过程都由一个内核线程反对,因而只有先反对内核线程,能力有轻量级过程。用户线程与内核线程的对应关系有三种模型:一对一模型、多对一模型、多对多模型,在这以4个内核线程、3个用户线程为例对三种模型进行阐明。 一对一模型 对于一对一模型来说,一个用户线程就惟一地对应一个内核线程(反过来不肯定成立,一个内核线程不肯定有对应的用户线程)。这样,如果CPU没有采纳超线程技术(如四核四线程的计算机,就如上图展现的我应用的计算机),一个用户线程就惟一地映射到一个物理CPU的线程,线程之间的并发是真正的并发。一对一模型使用户线程具备与内核线程一样的长处,一个线程因某种原因阻塞时其余线程的执行不受影响;此处,一对一模型也能够让多线程程序在多处理器的零碎上有更好的体现。但一对一模型也有两个毛病: 1.许多操作系统限度了内核线程的数量,因而一对一模型会使用户线程的数量受到限制; 2.许多操作系统内核线程调度时,上下文切换的开销较大,导致用户线程的执行效率降落。多对一模型 多对一模型将多个用户线程映射到一个内核线程上,线程之间的切换由用户态的代码来进行,因而绝对一对一模型,多对一模型的线程切换速度要快许多;此外,多对一模型对用户线程的数量简直无限度。但多对一模型也有两个毛病: 1.如果其中一个用户线程阻塞,那么其它所有线程都将无奈执行,因为此时内核线程也随之阻塞了; 2.在多处理器零碎上,处理器数量的减少对多对一模型的线程性能不会有显著的减少,因为所有的用户线程都映射到一个处理器上了。多对多模型 多对多模型联合了一对一模型和多对一模型的长处,将多个用户线程映射到多个内核线程上。多对多模型的长处有: 1.一个用户线程的阻塞不会导致所有线程的阻塞,因为此时还有别的内核线程被调度来执行; 2.多对多模型对用户线程的数量没有限度; ...

December 17, 2020 · 1 min · jiezi