Linux 抢占式线程与非抢占式线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4147221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:55:43  来源:igfitidea点击:

Preemptive threads Vs Non Preemptive threads

linuxmultithreadingunixpthreads

提问by Alok Save

Can someone please explain the difference between preemptive Threading model and Non Preemptive threading model?

有人可以解释抢占式线程模型和非抢占式线程模型之间的区别吗?

As per my understanding:

按照我的理解:

  • Non Preemptive threading model:Once a thread is started it cannot be stopped or the control cannot be transferred to other threads until the thread has completed its task.
  • Preemptive Threading Model:The runtime is allowed to step in and hand control from one thread to another at any time. Higher priority threads are given precedence over Lower priority threads.
  • 非抢占式线程模型:线程一旦启动就不能停止或控制权不能转移到其他线程,直到线程完成其任务。
  • 抢占式线程模型:允许运行时随时介入并将控制权从一个线程转移到另一个线程。高优先级线程优先于低优先级线程。

Can someone please:

有人可以请:

  1. Explain if the understanding is correct.
  2. Explain the advantages and disadvantages of both models.
  3. An example of when to use what will be really helpful.
  4. If i create a thread in Linux (system v or Pthread) without mentioning any options(are there any??) by default the threading model used is preemptive threading model?
  1. 解释一下理解是否正确。
  2. 解释两种模型的优缺点。
  3. 何时使用真正有用的示例。
  4. 如果我在 Linux(system v 或 Pthread)中创建一个线程而不提及任何选项(有没有??)默认情况下使用的线程模型是抢占线程模型?

采纳答案by Jerry Coffin

  1. No, your understanding isn't entirely correct. Non-preemptive (aka cooperative) threads typically manually yield control to let other threads run before they finish (though it is up to that thread to call yield()(or whatever) to make that happen.
  2. Preempting threading is simpler. Cooperative threads have less overhead.
  3. Normally use preemptive. If you find your design has a lot of thread-switching overhead, cooperative threads would be a possible optimization. In many (most?) situations, this will be a fairly large investment with minimal payoff though.
  4. Yes, by default you'd get preemptive threading, though if you look around for the CThreads package, it supports cooperative threading. Few enough people (now) want cooperative threads that I'm not sure it's been updated within the last decade though...
  1. 不,你的理解并不完全正确。非抢占(又名合作)线程通常手动让出控制权,让其他线程在它们完成之前运行(尽管由该线程调用yield()(或其他方式)来实现这一点。
  2. 抢占线程更简单。协作线程的开销较小。
  3. 通常使用抢占式。如果你发现你的设计有很多线程切换开销,协作线程将是一个可能的优化。在许多(大多数?)情况下,这将是一笔相当大的投资,但回报却很少。
  4. 是的,默认情况下您会获得抢占式线程,但如果您查看 CThreads 包,它支持协作线程。很少有人(现在)想要合作线程,但我不确定它是否在过去十年内更新过......

回答by derobert

Non-preemptive threads are also called cooperative threads. An example of these is POE (Perl). Another example is classic Mac OS (before OS X). Cooperative threads have exclusive use of the CPU until they give it up. The scheduler then picks another thread to run.

非抢占式线程也称为协作线程。其中一个例子是 POE (Perl)。另一个例子是经典的 Mac OS(在 OS X 之前)。协作线程在放弃之前独占 CPU。调度程序然后选择另一个线程运行。

Preemptive threads can voluntarily give up the CPU just like cooperative ones, but when they don't, it will be taken from them, and the scheduler will start another thread. POSIX & SysV threads fall in this category.

抢占式线程可以像协作线程一样主动放弃CPU,但是当它们不这样做时,它将从它们那里拿走,并且调度程序将启动另一个线程。POSIX 和 SysV 线程属于这一类。

Big advantages of cooperative threads are greater efficiency (on single-core machines, at least) and easier handling of concurrency: it only exists when you yield control, so locking isn't required.

协作线程的一大优势是更高的效率(至少在单核机器上)和更容易处理并发:它只存在于您让出控制权时,因此不需要锁定。

Big advantages of preemptive threads are better fault tolerance: a single thread failing to yield doesn't stop all other threads from executing. Also normally works better on multi-core machines, since multiple threads execute at once. Finally, you don't have to worry about making sure you're constantly yielding. That can be really annoying inside, e.g., a heavy number crunching loop.

抢占式线程的一大优点是更好的容错性:单个线程未能让步并不会阻止所有其他线程执行。通常在多核机器上也能更好地工作,因为多个线程同时执行。最后,您不必担心确保您不断屈服。这在内部真的很烦人,例如,一个繁重的数字运算循环。

You can mix them, of course. A single preemptive thread can have many cooperative threads running inside it.

当然,您可以混合使用它们。一个抢占式线程可以在其中运行多个协作线程。

回答by pooria

If you use non-preemptiveit does not mean that process doesn't perform context switching when the process is waiting for I/O. The dispatcher will choose another process according to the scheduling model. We have to trust the process.

如果使用非抢占式,并不意味着进程在等待 I/O 时不执行上下文切换。调度器会根据调度模型选择另一个进程。我们必须相信这个过程。

non-preemptive:

非抢占式:

  1. less context switching, less overheadthat can be sensible in non-preemptive model

  2. Easier to handle since it can be handled on a single-core processor

  1. 更少的上下文切换,更少的开销,在非抢占式模型中是明智的

  2. 更容易处理,因为它可以在单核处理器上处理

preemptive:

先发制人

Advantage:

优势:

  1. In this model, we have a priority that helps us to have more control over the running process

  2. Better concurrency is a bounce

  3. Handling system calls without blocking the entire system

  1. 在这个模型中,我们有一个优先级,可以帮助我们更好地控制正在运行的进程

  2. 更好的并发性是反弹

  3. 在不阻塞整个系统的情况下处理系统调用

Disadvantage:

坏处:

  1. Requires more complex algorithms for synchronization and critical section handling is inevitable.

  2. The overhead that comes with it

  1. 需要更复杂的同步算法和临界区处理是不可避免的。

  2. 随之而来的开销

回答by Amimo Benja

In cooperative (non-preemptive)models, once a thread is given control it continues to run until it explicitly yields control or it blocks.

协作(非抢占式)模型中,一旦线程获得控制权,它就会继续运行,直到它明确放弃控制权或阻塞为止。

In a preemptive model, the virtual machine is allowed to step in and hand control from one thread to another at any time. Both models have their advantages and disadvantages.

抢占式模型中,虚拟机可以随时介入并将控制权从一个线程转移到另一个线程。两种模型都有其优点和缺点。

Java threads are generally preemptive between priorities. A higher priority thread takes precedence over a lower priority thread. If a higher priority thread goes to sleep or blocks, then a lower priority thread can run (assuming one is available and ready to run).

Java 线程通常在优先级之间抢占。较高优先级的线程优先于较低优先级的线程。如果较高优先级的线程进入睡眠状态或阻塞,则可以运行较低优先级的线程(假设一个线程可用并准备好运行)。

However, as soon as the higher priority thread wakes up or unblocks, it will interrupt the lower priority thread and run until it finishes, blocks again, or is preempted by an even higher priority thread.

然而,一旦较高优先级的线程唤醒或解除阻塞,它就会中断较低优先级的线程并运行直到它完成、再次阻塞或被更高优先级的线程抢占。

The Java Language Specification, occasionally allows the VMs to run lower priority threads instead of a runnable higher priority thread, but in practice this is unusual.

Java 语言规范偶尔允许 VM 运行优先级较低的线程而不是可运行的较高优先级的线程,但实际上这是不寻常的。

However, nothing in the Java Language Specification specifies what is supposed to happen with equal priority threads. On some systems these threads will be time-sliced and the runtime will allot a certain amount of time to a thread. When that time is up, the runtime preempts the running thread and switches to the next thread with the same priority.

然而,Java 语言规范中并没有规定在同等优先级的线程中应该发生什么。在某些系统上,这些线程将按时间分片,并且运行时将为线程分配一定的时间。当该时间到时,运行时会抢占正在运行的线程并切换到具有相同优先级的下一个线程。

On other systems, a running thread will not be preempted in favor of a thread with the same priority. It will continue to run until it blocks, explicitly yields control, or is preempted by a higher priority thread.

在其他系统上,正在运行的线程不会被优先级相同的线程抢占。它将继续运行,直到它阻塞、明确让出控制权或被更高优先级的线程抢占。

As for the advantages both derobert and pooria have highlighted them quite clearly.

至于优势,derobert 和pooria 都非常清楚地突出了它们。