有人可以解释先发制人线程模型和非先发制人线程模型之间的区别吗?
根据我的理解:
有人可以:
答案 0 :(得分:35)
yield()
(或其他)来实现这一点。答案 1 :(得分:20)
非抢先线程也称为协作线程。这些的一个例子是POE(Perl)。另一个例子是经典Mac OS(在OS X之前)。协作线程专用CPU,直到它们放弃。然后调度程序选择另一个要运行的线程。
抢先线程可以像协作线程一样自愿放弃CPU,但是当它们没有时,它将从它们中获取,并且调度程序将启动另一个线程。 POSIX& SysV线程属于这一类。
协作线程的巨大优势是效率更高(至少在单核机器上)和更容易处理并发:它只在你产生控制时才存在,因此不需要锁定。
抢占线程的巨大优势是更好的容错能力:单个线程无法产生不会阻止所有其他线程执行。由于多个线程同时执行,因此通常在多核机器上工作得更好。最后,你不必担心确保你不断屈服。这在内部可能非常烦人,例如,大量的运算循环。
当然,你可以混合使用它们。单个抢占线程可以在其中运行许多协作线程。
答案 2 :(得分:7)
如果您使用非抢占式,则并不意味着当进程等待I / O时,进程不会执行上下文切换。调度员将根据调度模型选择另一个进程。在这个模型中,我们必须相信这个过程。
<强>非抢占:强>
1.无上下文切换=少头顶,这在非抢先模型中是明智的
2.它更容易处理,因为它可以在单核处理器上处理
<强>抢占强>:
<强>优势:强>
1.在这个模型中,我们优先考虑可以帮助我们更好地控制运行过程
2.我们可以看到更好的并发性
3.我们可以在不阻塞整个系统的情况下处理系统调用
<强>缺点:强>
1.我们需要复杂的锁定算法,我们有应该处理的关键部分问题
2.经常支付一大笔费用
答案 3 :(得分:0)
在合作(非抢占式)模型中,一旦线程获得控制权,它将继续运行,直到明确产生控制权或阻塞为止。
在抢占模式中,允许虚拟机随时介入并将控制权从一个线程转移到另一个线程。两种模型都有其优点和缺点。
通常,Java线程在优先级之间是抢占式的。较高优先级的线程优先于较低优先级的线程。如果较高优先级的线程进入睡眠或阻塞状态,则可以运行较低优先级的线程(假设有一个可用线程并准备运行)。
但是,一旦较高优先级的线程唤醒或解除阻塞,它将中断较低优先级的线程并运行,直到完成,再次阻塞或被更高优先级的线程抢占。
Java语言规范偶尔允许VM运行较低优先级的线程,而不是运行可运行的较高优先级的线程,但这在实践中是不寻常的。
但是,Java语言规范中没有任何内容指定优先级相等的线程应该发生的情况。在某些系统上,这些线程将被分时,运行时将为线程分配一定的时间。时间到时,运行时会抢占正在运行的线程并切换到具有相同优先级的下一个线程。
在其他系统上,运行中的线程不会被优先级相同的线程抢占。它会继续运行,直到阻塞,显式产生控制权或被更高优先级的线程抢占。
关于德罗伯特和穷人的优势,他们都非常清楚地强调了它们。