2

我目前正在使用 Retlang 在 .NET 中进行基于消息的多线程,这是一个很棒的库。我不再有显式锁,每个线程都在做自己的事情,管理应用程序的一部分并通过消息与其他线程通信。

我现在必须实现我的应用程序的一项功能,该功能也可以有自己的发布者/订阅者线程。唯一的问题是这个线程实际上会做很少的工作。预计每 10 分钟左右会收到来自发布者的消息。当收到一条消息时,它会做一些工作,但不会超过几百毫秒。

所以我开始怀疑让一个线程在 99.9% 的时间里处于休眠状态是否真的是一个不错的选择。这种操作有线程池,但由于我无法控制接收消息的线程,所以我不得不求助于丑陋的、容易出错的锁。

我的问题是:在资源方面,让线程闲置,等待绝大多数时间真的是个问题吗?在使用良好的基于​​消息的架构之后使用共享多线程感觉就像回到过去,而且它将是应用程序中唯一带有锁的部分。但我一直在想“我在这里做错了吗?” 用这个线程。

编辑:谢谢大家,在阅读了你们的每一个答案后,我决定另一个线程不是那么大的问题。我的应用程序将仅与基于消息的多线程保持一致,如果我真的有性能问题(但不应该是这样),我会进一步调查。

4

7 回答 7

3

我实际上会争辩说,将 ThreadPool 用于大部分时间都在休眠的线程是一个糟糕的设计选择 -

让一个线程休眠(或者,更好的是,等待一个事件)在您的应用程序中几乎没有开销。使用专用线程的主要缺点是线程需要分配自己的堆栈,因此与线程池线程相比,您将使用一些额外的内存。

于 2010-06-28T19:16:04.647 回答
2

这听起来像是使用Task. 他们默认使用下面的线程池,但有一个更进化的 API。

于 2010-06-28T19:15:19.997 回答
1

虽然 PoolFiber 上的每个操作都可以在单独的池线程中执行,但特定 PoolFiber 的操作按顺序执行而不是并行执行,一次只能执行一个池线程。

PoolFiber 应该可以满足您的需求。

于 2010-07-01T03:31:15.007 回答
1

您不能PoolFiber为此使用 Retlang 吗?它不是由像ThreadFiber.Net 线程池那样的专用线程支持的。这意味着您可以继续使用在整个应用程序中使用的相同 Retlang 语义,而无需保持空闲线程。

于 2010-06-28T19:20:50.967 回答
0

我会说有一个专门的线程来接收这些消息很好。我什至可以说这将是首选方法。这不像您只是随意创建线程或类似的东西。我们在这里讨论的是一个额外的线程,它不会消耗很多资源(可能会占用一点堆栈空间)。在我看来,不必担心共享状态的额外同步(当然除了消息传递)的优点胜过缺点。

于 2010-06-28T19:24:07.627 回答
0

您应该考虑使用 F#。它非常适合在不烧线程的情况下对逻辑单线程代理进行编程(例如,代理可以在 ThreadPool 上跳跃,但仍以序列化方式响应消息,并且在其邮箱中到达的消息将它们唤醒并安排 ThreadPool 工作)。

http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx

于 2010-06-28T19:25:50.720 回答
0

我认为这基本上是一个优化问题。您的应用程序是否存在性能问题(特别是内存问题)?如果没有,那么继续让线程空闲并保持代码更干净。一旦你有真正的理由,就探索其他选择。

于 2010-06-28T19:16:54.097 回答