明显的多线程反对意见是复杂性和令人讨厌的错误。多进程可能会影响性能,因为IPC通信和上下文切换。
"Unix编程艺术" 这里 讨论了这个问题。
你会推荐基于进程的系统(如Apache)还是多线程方法?
两者都有各自的复杂和复杂之处。
你可以选择其中任意一种。从宏观上讲,选择哪种可能并不重要。重要的是你做得有多好。因此:
做你最有经验的事情。 或者如果你领导一个团队,就做团队最有经验的事情。
--- 线程!---
我做了很多线程编程,我喜欢其中的某些部分,但也有一些部分我不喜欢。我学到了很多东西,现在通常可以写一个多线程应用程序而不会太痛苦,但它必须以非常特定的方式编写。即:
1)必须使用非常清晰定义的数据边界来编写,这些数据边界是100%线程安全的。否则,任何可能发生的情况都会发生,并且可能不是当您拥有调试器时...而且调试线程代码就像窥视Schrödinger的盒子...通过看进去,其他线程可能已经处理更多的内容。
2)必须编写压力测试机器的测试代码。许多多线程系统只在机器受到重压时显示其错误。
3)必须有一些非常聪明的人拥有数据交换代码。如果有任何捷径可以走,某些开发人员可能会走这条路,您将遇到一个错误的bug。
4)必须有抓住所有情况并以最小的麻烦重置应用程序的情况。这是因为生产代码会因为某些线程问题而失败。简而言之:show must go on。
---跨进程!---
我对基于进程的线程编程经验较少,但最近在Windows中进行了一些跨进程操作(其中IPC是Web服务调用...WOO!),这相对干净且简单,但我也遵循一些规则。总的来说,进程间通信会更加容错,因为程序非常好地接收来自外部世界的输入..而且这些传输机制通常是异步的。无论如何...
1) 定义清晰的流程边界和通信机制。使用TCP、Web服务、管道等消息/事件传递方式都可以,只要边界清晰,并且在这些边界上有大量的验证和错误检查代码。
2) 准备好应对瓶颈。代码容错性非常重要。我的意思是,有时候您可能无法写入那个管道。您必须能够重新排队并尝试再次发送消息,而不会导致应用程序锁定/抛出异常。
3) 一般情况下需要编写更多的代码,因为跨进程边界传输数据意味着您必须以某种方式对其进行序列化。这可能成为问题的源头,特别是当您开始维护和更改该代码时。
希望这能帮到您。
然而,还有其他问题需要考虑。您将在什么样的系统上运行?如果您在单处理器系统上产生几个进程,则根据您可以指定的某些其他细节,您肯定不会获得太多好处。如果您描述一下您要解决的问题的性质,我们可以提供更进一步的帮助。
取决于您想使用哪种编程语言(以及哪些库)。
个人而言,我会选择多线程,因为我知道与线程相关的问题(以及如何解决它们)。
如果您想在多台计算机上运行守护程序并将负载分配给它们,则多处理可能会有所帮助,但我认为这不是一个主要问题。
好的,最终我们实现了一个多进程系统,使用管道进行进程间通信,并且有一个记录器按需生成进程。类似于 Apache httpd。它完美地工作。
感谢大家的反馈。
我决定采用类似于Apache Web服务器的多进程架构。 这些进程将在多处理器/核心系统上良好地扩展。 通信将使用管道或套接字进行。
进程将准备好在进程池中使用,因此没有进程生成成本。
与我所获得的健壮性相比,性能损失将是微不足道的。
select(2)
的单线程应用程序可能适合你的需求,并且不具有进程或线程的缺点。这需要您能够将所有I/O集中到一个中心位置,最有可能通过回调分派到其他模块,但除非您有很多想要进行自己的I/O并且无法以这种方式重组的库,否则这并不难。