[英]Message-based multithreading or Thread Pool for a short and uncommon action?
我目前正在使用Retlang在.NET中基于消息的多线程,这是一个很棒的库。 我再也没有显式的锁了,每个线程都在做自己的事,管理应用程序的一部分,并通过消息与其他线程通信。
现在,我必须实现我的应用程序的功能,该功能也可以具有自己的发布者/订阅者线程。 唯一的问题是,该线程实际上将完成很少的工作。 预计每10分钟左右会收到发布者的消息。 收到消息后,它将完成一些工作,但没有任何事情需要花费数百毫秒的时间。
因此,我开始怀疑是否有一个线程在99.9%的时间内处于睡眠状态实际上是一个不错的选择。 有用于这种操作的线程池,但是由于我无法控制将接收消息的线程,因此我不得不求助于难看的,容易出错的锁。
我的问题是:从资源角度来看,让线程空闲并等待绝大多数时间真的是一个问题吗? 在使用基于消息的良好体系结构之后使用共享多线程感觉就像回到了过去,而且它将是应用程序中唯一带有锁的部分。 但是我一直在想:“我在这里做错了吗?” 这个线程。
编辑 :谢谢大家,在阅读完您的所有答案后,我认为另一个线程并不是什么大问题。 我的应用程序将仅与基于消息的多线程保持一致,如果我确实有性能问题(但事实并非如此),我将作进一步调查。
我实际上会争辩说,对于大多数时间处于休眠状态的线程使用ThreadPool是一个糟糕的设计选择-
使单个线程处于休眠状态(或者更好的是等待事件)在应用程序中的开销很小。 使用专用线程的主要缺点是线程将需要分配自己的堆栈,因此与线程池线程相比,您将使用一些额外的内存。
这听起来像是使用Task
的理想方案。 他们默认使用下面的线程池,但具有更先进的API。
您不能为此使用Retlang的PoolFiber
吗? 它没有像ThreadFiber
这样的专用线程支持,而是由.Net线程ThreadFiber
支持的。 这意味着您可以在整个应用程序中继续使用相同的Retlang语义,而无需保留空闲线程。
尽管PoolFiber上的每个操作都可以在单独的池线程中执行,但是特定PoolFiber的操作是顺序执行而不是并行执行,一次只能执行一个池线程。
PoolFiber应该可以满足您的需求。
我认为这基本上是一个优化问题。 您的应用程序是否存在性能问题(特别是内存问题)? 如果不是,则继续使线程空闲,并保持代码清洁。 有真正的理由后,再探索其他选择。
我想说有一个专门的线程来接收这些消息很好。 我什至可以说这将是首选方法。 并不是说您只是在随意创建线程或类似的东西。 我们在这里讨论的是一个额外的线程,它不会消耗很多资源(也许会占用很少的堆栈空间)。 在我看来,不必担心共享状态的额外同步(当然除了消息传递之外)的好处胜过了缺点。
您应该考虑使用F#。 这对于在不燃烧线程的情况下对逻辑单线程代理进行编程非常有用(例如,代理可以跳到ThreadPool,但是仍然以序列化的方式响应消息,到达其邮箱的消息会唤醒它们并安排ThreadPool工作)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.