multithreading 多线程,何时屈服与睡眠
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2668546/
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
Multithreading, when to yield versus sleep
提问by Anycorn
To clarify terminology, yield is when thread gives up its time slice. My platform of interest is POSIX threads, but I think the question is general.
为了澄清术语,yield 是线程放弃其时间片的时间。我感兴趣的平台是 POSIX 线程,但我认为这个问题很普遍。
Suppose I have consumer/producer pattern. If I want to throttle either consumer or producer, which is better to use, sleep or yield? I am mostly interested in efficiency of using either function.
假设我有消费者/生产者模式。如果我想限制消费者或生产者,使用、睡眠或产量哪个更好?我最感兴趣的是使用任一功能的效率。
采纳答案by Justin Ethier
The "right" way to code a producer / consumer is to have the consumer wait for the producer's data. You can achieve this by using a synchronization object such as a Mutex. The consumer will Wait
on the mutex, which blocks it from executing until data is available. In turn, the producer will signal the mutex when data is available, which will wake up the consumer thread so it can begin processing. This is more efficient than sleep
in terms of both:
对生产者/消费者进行编码的“正确”方式是让消费者等待生产者的数据。您可以通过使用诸如互斥体之类的同步对象来实现这一点。消费者将Wait
使用互斥锁,这会阻止它执行,直到数据可用。反过来,当数据可用时,生产者将向互斥锁发送信号,这将唤醒消费者线程,以便它可以开始处理。这比sleep
两者都更有效:
- CPU utilization (no cycles are wasted), and
- Run Time (execution begins as soon as data is available, not when a thread is scheduled to wake up).
- CPU 利用率(不浪费任何周期),以及
- 运行时间(在数据可用时立即开始执行,而不是在调度线程唤醒时开始执行)。
That said, here is an analysis of yield vs sleep that you asked for. You may need to use such a scheme if for some reason waiting for output is not feasible:
也就是说,这是您要求的产量与睡眠的分析。如果由于某种原因等待输出不可行,您可能需要使用这样的方案:
It depends how much traffic you are receiving - if data is constantly being received and processed, you might consider doing a yield. However in most cases this will result in a "busy" loop that spends most of its time needlessly waking up the thread to check if anything is ready.
这取决于您收到多少流量 - 如果数据不断被接收和处理,您可能会考虑进行收益。然而,在大多数情况下,这将导致一个“忙”循环,它花费大部分时间不必要地唤醒线程以检查是否有任何准备就绪。
You will probably want to either sleep for a short period of time (perhaps for less than a second, using usleep
) OR even better use a synchronization object such as a mutex to signal that data is available.
您可能希望睡眠一小段时间(可能不到一秒钟,使用usleep
),或者甚至更好地使用同步对象(例如互斥锁)来表示数据可用。
回答by Ernelli
sleep and yield are not the same. When calling sleep the process/thread gives CPU to another process/thread for the given amount of time.
sleep 和 yield 是不一样的。当调用 sleep 时,进程/线程在给定的时间内将 CPU 分配给另一个进程/线程。
yield relinquishes the CPU to another thread, but may return immediately if there are no other threads that waits for CPU.
yield 将 CPU 交给另一个线程,但如果没有其他线程等待 CPU,则可能会立即返回。
So if you want to throttle, for example when streaming data at regular intervals, then sleep or nanosleep are the functions to use.
因此,如果您想节流,例如在定期流式传输数据时,则可以使用 sleep 或 nanosleep 功能。
If synchronization between producer/consumer is needed, you should use a mutex/conditional wait.
如果需要生产者/消费者之间的同步,您应该使用互斥/条件等待。
回答by John Vint
One good reason to sleep instead of yield is when there is too much contention at a specific critical section. Lets say for example you try to acquire two locks and there is a lot of contention on both locks. Here you can use sleep to employ an exponential back off. This would allow each failed attempt to pseudo randomly back off to allow other thread to succeed.
休眠而不是屈服的一个很好的理由是当特定临界区有太多争用时。例如,假设您尝试获取两个锁,并且两个锁都存在大量争用。在这里,您可以使用 sleep 来采用指数回退。这将允许每次失败的尝试伪随机退避以允许其他线程成功。
Yielding in this situation doesn't really help as much because the prospect of a random back off can increase likelihood that thread starvation would not occur.
在这种情况下让步并没有多大帮助,因为随机退避的可能性会增加不会发生线程饥饿的可能性。
Edit: Though I know this isn't necessarily java specific. Java's implementation of Thread.sleep(0)
has the same effect of Thread.yield()
At that point its more of a matter of style.
编辑:虽然我知道这不一定是特定于 Java 的。Java 的实现Thread.sleep(0)
具有相同的效果Thread.yield()
在这一点上,它更多的是风格问题。
回答by Onur
In java, some JVM implementations treat Thread.yield() as no-op, meaning it may have no effect. Calling Thread.sleep() does not necessarily mean that scheduler should yield the CPU to another thread; this is implementation dependent too. It may context-switch to another thread that is waiting or it may not in order to amortize the cost associated with context-switch.
在 Java 中,一些 JVM 实现将 Thread.yield() 视为无操作,这意味着它可能没有效果。调用 Thread.sleep() 并不一定意味着调度器应该将 CPU 交给另一个线程;这也取决于实现。它可能会上下文切换到另一个正在等待的线程,也可能不会为了分摊与上下文切换相关的成本。