如何设计多线程应用程序

dim*_*mba 5 c++ multithreading

我有一个多线程的应用程序.每个模块都在一个单独的线程中执行.模块是:

- network module - used to receive/send data from network
- parser module - encode/decode network data to internal presentation
- 2 application module - perform some application logic on the above data one after other
- counter module - used to gather statistics from other modules
- timer module - used to schedule timers
- and much more ...
Run Code Online (Sandbox Code Playgroud)

所有线程都使用消息队列进行线程间通信(通过条件变量和互斥锁进行std :: deque同步).

一些模块被其他模块使用(例如,所有模块都使用定时器和计数器),并且对于从网络接收的每个消息,这应该以非常高的速率处理.

这是非常复杂的应用程序,设计看起来"合理".另一方面,我不确定这样的设计,每个模块的线程是"最好的"吗?特别是,我担心这样的设计"包装"了很多上下文切换.

你怎么看?

是否有任何好的指导方针或开源项目可以学习如何对线程应用程序进行"正确"设计?

Chr*_*cke 22

每个函数的线程设计都是天真的:他们假设通过将任务(通过模块)分离到线程上,可以实现某种可伸缩性.

这种设计效率低下,因为很少有任务中断产生与CPU相同的任务.

更合理的设计是将任务分解为"工作" - 然后使用线程池机制来分配这些工作.每个模块线程方法的优点:

  • 线程池利用了所有核心.如果你有模块<core,那么你可以使用每个模块的线程.

  • 线程池通过维护活动线程和核心之间的奇偶校验来最小化争用和资源.使用每个模块的线程,如果模块>核心,您需要进行不必要的额外上下文切换,并且(在某些平台上)每个线程耗尽其他有限的每个进程资源(如虚拟内存).

  • 线程池让"模块"一次完成多个作业.每个模块的线程意味着最繁忙的模块仍然只有一个核心.


The*_*ish 7

我不会称自己为多线程设计专家.但我至少使用线程足以遇到各种问题,试图将它们设计为一起工作(通信,锁定资源,等待线程结束等).

在这一点上,我的一般经验法则是我必须证明每个新线程的存在.例如,如果我正在使用的网络层同时提供同步和异步API,那么我真的可以证明网络代码在新线程中使用同步调用而不是仅使用主线程中的异步调用吗?在您的情况下,由于特定原因,有多少模块实际上需要自己的线程.有没有可以反过来从主线程轮流调用?

如果某些线程没有充分的理由存在,那么您可以通过将该模块放在主线程中来节省一些麻烦和复杂性.

当然,现在有充分理由把事情放在线程中.例如,进行可能长时间阻塞的同步调用,在执行长任务时保持GUI线程响应,或者能够利用多核系统上的大任务的并行处理.

我不知道有任何特殊的"正确"方法.很多事情都归结为您的应用程序实际应该做的事情的细节.