当前位置:  开发笔记 > 运维 > 正文

用户级线程的好处

如何解决《用户级线程的好处》经验,为你挑选了1个好方法。

我正在研究用户级线程和内核级线程之间的差异,我基本上理解这一点.
我不清楚的是完全实现用户级线程的重点.

如果内核不知道单个进程中存在多个线程,那么我可以体验到哪些好处?
我已经阅读了几篇文章,声明只有当这样的线程不执行阻塞操作(这会导致整个进程被阻塞)时,建议用户级别的线程实现.

这就是说,考虑到它们无法利用多个处理器和独立调度,所有线程的顺序执行和它们的"并行"执行之间的区别是什么?

回答之前提出的问题(类似于我的问题)是这样的:

没有现代操作系统实际上将n用户级线程映射到1 内核级线程.

但由于某种原因,互联网上的许多人都声称用户级线程永远不会利用多个处理器.

你能帮我理解一下吗?



1> cadaniluk..:

我强烈建议现代操作系统4 版由安德鲁·斯图尔特·塔能鲍姆(在节目如主演的关于Linux的争论 ;也参与:Linus Torvalds的).耗费了大量的钱,但如果你真的想知道的话,这绝对是值得的.对于渴望学生和绝望的爱好者来说,这很棒.

你的问题得到解答

[...]我不清楚的是完全实现用户级线程的重点.

阅读我的帖子.这是全面的,我敢说.

如果内核不知道单个进程中存在多个线程,那么我可以体验到哪些好处?

请阅读下面的"缺点"部分.

我已经阅读了一些文章,其中指出只有当这样的线程不执行阻塞操作(这会导致整个进程被阻塞)时,建议用户级线程的实现.

阅读"缺点"中的"不与系统调用协调"小节.


所有引用都来自我在本答案的顶部,第2.2.4节"在用户空间中实现线程"中推荐的那本书.

好处

在没有线程的系统上启用线程

第一个优点是用户级线程是一种在没有线程的情况下使用系统上的线程的方法.

第一个也是最明显的优点是 可以在不支持线程的操作系统上实现用户级线程包.过去所有操作系统都属于这一类,即使现在仍有一些操作系统仍然存在.

无需内核交互

另一个好处是切换线程时的开销很小,而不是切换到内核模式,做东西,切换回来等.较轻的线程切换在书中描述如下:

当一个线程执行可能导致它在本地被阻塞的东西时,例如,等待其进程中的另一个线程完成某些工作,它会调用一个运行时系统过程.此过程检查线程是否必须进入阻塞状态.如果,那么它存储线程的寄存器(即它自己的)[...]并用新线程的保存值重新加载机器寄存器.一旦切换指针和程序计数器,新线程就会自动重新生效.如果机器碰巧有一个存储所有寄存器的指令而另一个指令要将它们全部加载,那么整个线程切换只需要在少数几个指令中完成.像这样进行线程切换至少是一个数量级 - 可能比捕获内核更快 - 并且是支持用户级线程包的强有力论据.

这种效率也很好,因为它使我们免于非常繁重的上下文切换和所有这些.

单独调整的调度算法

而且,因此没有中央调度算法,每个过程都可以有自己的调度算法,并且在各种选择方面更灵活.此外,"私有"调度算法对于从线程获得的信息更加灵活.信息的数量可以手动和按进程调整,因此它非常精细.这是因为,同样没有中央调度算法需要满足每个过程的需要; 它必须非常通用,并且必须在每种情况下都能提供足够的性能.用户级线程允许非常专业的调度算法.
这仅受"不自动切换到调度程序"的缺点的限制.

它们[用户级线程]允许每个进程拥有自己的自定义调度算法.对于某些应用程序,例如,具有垃圾收集器线程的应用程序,不必担心线程在不方便的时刻停止是一个加号.它们也可以更好地扩展,因为内核线程总是需要内核中的一些表空间和堆栈空间,如果存在大量线程,这可能是一个问题.


缺点

没有与系统调用协调

用户级调度算法不知道某个线程是否已调用阻塞read系统调用.OTOH是一种内核级调度算法,因为可以通过系统调用通知它; 两者都属于内核代码库.

假设线程在击中任何键之前从键盘读取.让线程实际进行系统调用是不可接受的,因为这将停止所有线程.首先拥有线程的主要目标之一是允许每个线程使用阻塞调用,但是为了防止一个被阻塞的线程影响其他线程.通过阻止系统调用,很难看出如何轻松实现此目标.

他认为系统调用可能是非阻塞的,但这将非常不方便,并且与现有操作系统的兼容性将受到严重损害.
Tanenbaum先生还说,可以修改系统调用周围的库包装(例如glibc中找到的)以预测系统校准何时阻止使用,select但他说这是不优雅的.

在此基础上,他说线程经常会阻塞.通常阻塞需要许多系统调用.许多系统调用都很糟糕.并且没有阻塞,线程变得不那么有用:

对于基本上完全受CPU约束且很少阻塞的应用程序,有线程的重点是什么?没有人会认真考虑n使用线程计算第一个素数或下棋,因为这样做没有任何好处.

如果不知道线程,页面错误会阻止每个进程

操作系统没有线程概念.因此,如果发生页面错误,将阻止整个进程,从而有效地阻止所有用户级线程.

与阻塞系统调用的问题有点类似的是页面错误的问题.[...]如果程序调用或跳转到不在内存中的指令,则会发生页面错误,操作系统将从磁盘获取丢失的指令(及其邻居).[...]当找到并读入必要的指令时,进程被阻塞.如果一个线程导致页面错误,内核甚至不知道线程的存在,自然会阻塞整个进程直到磁盘I/O即使其他线程可能是可运行的,也是完整的.

我认为这可以推广到所有中断.

没有自动切换到调度程序

由于没有每进程时钟中断,因此线程将永远获取CPU,除非发生某些依赖于操作系统的机制(例如上下文切换)或者它自愿释放CPU.
这可以防止通常的调度算法工作,包括Round-Robin算法.

[...] 如果一个线程开始运行,除非第一个线程自愿放弃CPU,否则该进程中的其他线程都不会运行. 在一个进程中,没有时钟中断,因此无法以循环方式(轮流)安排进程. 除非线程以自己的意愿进入运行时系统,否则调度程序永远不会有机会.

他说可能的解决方案是

[...]让运行时系统每秒一次请求一个时钟信号(中断)来控制它,但这也是粗略和混乱的编程.

我甚至会继续说,这样的"请求"需要进行一些系统调用,其缺点已在"不与系统调用协调"中解释.如果没有系统调用,那么程序将需要免费访问计时器,这是一个安全漏洞,在现代操作系统中是不可接受的.

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有