Windows,多个进程与多个线程

时间:2010-10-14 04:50:19

标签: windows multithreading process

我们必须使我们的系统具有高度可扩展性,并且它是使用VC ++为Windows平台开发的。最初说,我们想同时处理100个请求(来自msmq)。什么是最好的方法?单个过程有100个线程还是2个进程有50-50个线程?在第二种方法的情况下,除了过程存储器之外还有什么收益。在Windows中,首先将CPU时间分配给进程,然后在该进程的线程之间进行拆分,或者OS计算每个进程的线程数,并根据线程而不是进程来分配CPU。我们注意到,在第一种情况下,CPU利用率为15-25%,我们希望消耗更多的CPU。请记住,我们希望获得最佳性能,因此100个请求就是例如。我们还注意到,如果我们将进程的线程数增加到120以上,则性能会因上下文切换而降低。

还有一点;我们的产品已经支持群集,但我们希望在单个节点上使用更多的CPU。

任何建议都将受到高度赞赏。

2 个答案:

答案 0 :(得分:4)

您无法处理比CPU内核更多的请求。 “快速”可扩展解决方案涉及设置线程池,其中活动(未阻塞在IO)线程数= = CPU核心数。因此,因为要为100 msmq请求提供服务而创建100个线程并不是一个好设计。

Windows有一个名为IO Completion Ports的线程池机制。

使用IO完成端口确实将设计推送到单个进程,因为在多进程设计中,每个进程都有自己的IO完成端口线程池,它将独立管理,因此您可以获得更多的线程争用CPU核心。

IO完成端口的“核心”思想是它的内核模式队列 - 您可以手动将事件发布到队列,或通过关联文件(文件,套接字,管道)句柄自动发送到它的异步IO完成与港口。

另一方面,IO完成端口机制自动将事件出列到等待工作线程 - 但如果它检测到线程池中当前“活动”线程> = CPU核心数,则它不会使作业出列。

使用IO完成端口可能会大大增加服务的可扩展性,但通常增益远小于预期,因为当所有CPU核心争夺服务其他资源时,其他因素会迅速发挥作用。

如果你的服务是用c ++开发的,你可能会发现对堆的序列化访问是一个很大的性能减去 - 虽然Windows版本6.1似乎实现了一个低争用堆,所以这可能不是一个问题。

总结一下 - 从理论上讲,您最大的性能提升来自于使用单个进程管理的线程池的设计。但是,您严重依赖于您使用的库,而不是序列化对关键资源的访问,这可能会使您迅速失去所有理论性能增益。 如果你确实有库代码序列化你很好的线程化服务(就像c ++对象创建和销毁由于堆争用而被序列化)那么你需要将库/开关的使用更改为库的低争用版本或者只需扩展到多个流程。

要知道的唯一方法是编写以各种方式对服务器施加压力并测量结果的测试用例。

答案 1 :(得分:3)

Windows上的标准方法是多线程。不是说这总是你最好的解决方案,但每个线程或进程都要付出代价,而在Windows上,进程更昂贵。至于调度程序,我不确定,但你可以设置进程和线程的priory。线程的真正好处是它们的共享地址空间和没有IPC的通信能力,但必须小心保持同步。

如果您的系统已经开发出来,它可能更容易实现多进程解决方案,特别是如果有可能后者可以使用多台计算机。由于您在一台机器上的2个进程的IPC可以扩展到一般情况下的多台机器。大规模并行化的大多数尝试都失败了,因为整个系统都没有针对瓶颈进行评估。例如,如果你实现了100个写入同一个数据库的线程,你可能在实际性能上几乎没有什么好处,只需等待你的数据库。

只是我的.02