gpt4 book ai didi

.net - .NET中的生产者消费者链和线程调度

转载 作者:行者123 更新时间:2023-12-02 04:14:27 24 4
gpt4 key购买 nike

我制作了由4个生产者-消费者线程组成的链(形成4个步骤的管道)。令我惊讶的是,所有四个线程都按顺序运行,而不是同时运行!!!也就是说,第二个线程神秘地等待直到第一个线程完全完成生成为止。第三个线程神秘地等待直到第二个线程完全完成生成(依此类推)。

情况变得更糟。如果我将Thread.Sleep(300)放入第一个生产者的循环中,则其他三个线程将并发并实际上获得处理器时间,如预期的那样,并从多线程应用程序产生预期的“随机交错”控制台输出。我几乎无法接受“ sleep ”是解决方案的必要部分的想法,但是我看到code written by Jon Skeet正是以这种方式合并了 sleep 。

请告诉我,实现并发不是必需的,如果是并发,那么为什么是

关于我的特定生产者-消费者链的一个更精确的故事看起来像这样:

  • 第一个线程:处于紧密循环中,它会尽快生成“窗口小部件”消息,并将其插入下一个线程的队列中。当第一个窗口小部件添加到队列时,System.Threading.Timer设置为〜100毫秒。从计时器触发的回调是第二个线程...
  • 第二个线程(从计时器触发):从先前的队列中读取部分或全部小部件。它将它们发送到另一个队列(由第三个线程使用)。 monitor.Pulse/Wait机制用于与第三个线程同步。
  • 第三线程:在监视器上阻塞。等待直到monitor.Pulse被调用,然后从队列中获取一项。将一项插入最终队列,再次使用Monitor.Push完成后将其插入。
  • 第四个线程:在监视器上阻塞。请等待直到monitor.Pulse被调用。小部件已处理。

  • 要通过此管道处理100万个小部件,大约需要4分钟。在4分钟内,有足够的时间安排最后3个线程,并与第一个线程同时进行一些工作。但是正如我说的那样,最后三个线程是按顺序运行的,除非我为第一个线程引入了微小的 sleep 。这没有道理。

    对为什么这样工作有任何想法吗?

    p.s.请不要告诉我,正如我所描述的,长长的生产者-消费者链可以被缩减或消除。请相信我(或假设)我需要那么长的链条。 :)

    最佳答案

    紧密循环会影响多线程。听起来您的第一个线程运行得足够快,以至于第二个线程甚至没有机会启动。 请注意,如果发生这种情况,那么顺序解决方案是最有效的。 :)

    由于您的生产者/消费者布局有些复杂,因此我假设您在实际数据中看不到此行为。

    尽管可以通过添加带有非零参数的Thread.Sleep(请参阅Joe Duffy's blog entry on why this works)来解决此问题,或者只是忽略它,但是更好的解决方案是限制第一个生产者/消费者队列的大小。这将只允许第一个线程产生一定数量的小部件,然后阻塞直到管道的其余部分有机会启动。

    .NET 4.0 BlockingCollection<T>允许您指定最大大小。 Microsoft Rx library已将其反向移植到.NET 3.5,因此您可以根据需要使用它。 (我建议这样做,而不要使用内部解决方案)。

    关于.net - .NET中的生产者消费者链和线程调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3535276/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com