多线程,何时屈服与睡眠

时间:2010-04-19 15:15:06

标签: multithreading sleep yield

为了澄清术语,yield是线程放弃时间片的时间。 我感兴趣的平台是POSIX线程,但我认为这个问题很普遍。

假设我有消费者/生产者模式。如果我想扼杀消费者或生产者,哪个更好用,睡觉还是产量?我最感兴趣的是使用这两种功能的效率。

4 个答案:

答案 0 :(得分:10)

对生产者/消费者进行编码的“正确”方法是让消费者等待生产者的数据。您可以使用同步对象(如Mutex)来实现此目的。消费者将在互斥锁上Wait,阻止它执行直到数据可用。反过来,生产者将在数据可用时发出互斥信号,这将唤醒消费者线程,以便开始处理。就两者而言,这比sleep更有效:

  • CPU利用率(没有浪费周期)和
  • 运行时间(数据可用后立即开始执行,而不是在计划唤醒线程时执行)。

那就是说,这是你要求的产量与睡眠的分析。如果由于某种原因等待输出不可行,您可能需要使用这样的方案:

这取决于您接收的流量 - 如果不断收到和处理数据,您可能会考虑收益。然而,在大多数情况下,这将导致“忙”循环,其大部分时间花费在不必要地唤醒线程以检查是否有任何准备好。

您可能希望在短时间内睡眠(可能不到一秒,使用usleep)或者甚至更好地使用同步对象(如互斥锁)来表示数据可用。< / p>

答案 1 :(得分:10)

睡眠和产量不一样。当调用sleep时,进程/线程将CPU给予另一个进程/线程达到给定的时间。

yield将CPU放弃到另一个线程,但如果没有其他线程等待CPU,则可能立即返回。

因此,如果你想节流,例如定期流式传输数据,那么睡眠或纳米睡眠是要使用的功能。

如果需要生产者/消费者之间的同步,则应使用互斥/条件等待。

答案 2 :(得分:1)

睡眠而不是屈服的一个好理由是在特定关键部分存在太多争用。让我们说比如说你试图获得两个锁,并且两个锁都有很多争用。在这里你可以使用睡眠来使用指数退避。这将允许每次失败尝试伪随机退回以允许其他线程成功。

在这种情况下屈服并没有多大帮助,因为随机退避的可能性会增加线程饥饿不会发生的可能性。

编辑:虽然我知道这不一定是特定于java的。 Java Thread.sleep(0)的实现与Thread.yield()具有相同的效果。在这一点上,它更多地是一种风格问题。

答案 3 :(得分:0)

在java中,一些JVM实现将Thread.yield()视为no-op,这意味着它可能没有任何效果。调用Thread.sleep()并不一定意味着调度程序应该将CPU输出到另一个线程;这也是依赖于实现的。它可以上下文切换到正在等待的另一个线程,或者可能不是为了分摊与上下文切换相关联的成本。

相关问题