快速创建数千个线程并同时执行它们

时间:2010-10-12 21:22:22

标签: c# .net multithreading threadpool

我有一个C#.NET应用程序需要通知4000到40,000个连接设备,以便同时执行任务(或尽可能接近同步)。

该应用程序运行良好;但是,我对表现不满意。在一个完美的世界中,只要我发送命令,我希望所有设备同时响应。然而,似乎有一个延迟,因为我创建的所有线程都会启动并执行任务。

我使用.NET 4.0 ThreadPool,使用自定义线程创建了我自己的解决方案,我甚至调整了现有的ThreadPool,以允许一次执行更多线程。

我仍然想要更好的表现,这就是我在这里的原因。有任何想法吗?评论?建议?谢谢。

-Shaun

让我补充一点,应用程序通知这些“连接设备”他们需要在多播地址上监听音频。

7 个答案:

答案 0 :(得分:14)

双核超线程处理器可以同时执行4个线程 - 取决于线程正在做什么(没有IO争用或内存访问等)。一个四核超线程可能只有8个。但40K只是不能实际发生。

如果您希望附近同时进行,那么您最好在启动时尽可能多的线程与计算机具有可用内核并让每个线程触发通知然后结束。你会以这种方式摆脱一堆上下文切换。

或者,看看其他地方。正如SB在评论中建议的那样,使用UDP多播来通知侦听机他们应该做些什么。

答案 1 :(得分:12)

不能同时执行4000个线程,更不用说40k了。最好是在具有超线程的桌面盒上,最多可以同时进行8个进程(假设为四核)。线程是伪并行的,甚至没有深入研究总线争用的问题。

如果你绝对需要40k设备的同时性,你需要某种形式的硬件同步。

答案 2 :(得分:5)

听起来您可以控制每个设备上运行的软件。在这种情况下,您可以查看HPC的使用情况并分层构建您的设备(节点)和/或使用MPI来执行远程进程。

对于层次结构示例:指定8个节点作为主要主节点,同样具有8个从节点,每个从节点也可以充当8个从节点的主节点(您可能需要查看自动订阅算法来执行此操作)。您将拥有深度为6的层次结构以覆盖40,000个节点。每个主服务器都有一小部分代码在不断运行,等待指令传递给从服务器。

您所做的只是将指令传递给8个主控制器,并且您的指令将由主控器异步传播到线路上的“簇”。该指令最多只能传递5次,因此将快速传播。

另外(或结合)你可以看看MPI,这是一个无法解决的问题。有一些已建立的C#实现。

答案 3 :(得分:4)

创建数千个线程的开销非常大。我会寻求替代解决方案。这听起来像异步IO的工作:您的计算机可能只有一个网络连接,因此一次只能发送一条消息 - 线程无法改善!

答案 4 :(得分:3)

我是否正确地猜测您在设备上使用同步API调用,这就是为什么它必须在线程中执行? API是否具有异步版本的调用?如果设备API真的可以支持40k +设备,那么应该。它还应该具有内部处理,以便同步回调数据以进行回调所需的等待句柄(或等效句柄)。这不是您可以在客户端应用程序端处理的内容;您没有足够的可见性来了解设备API的底层实现,以了解如何并行化任务。正如您所发现的那样,使用阻塞调用创建40k线程并不会削减它。

答案 5 :(得分:2)

您应该对设备执行异步IO。这非常有效,并使用不同(更大)的线程集来处理一些工作。当然,设备将更快地接收命令。 IO线程池将处理回复(如果有)

答案 6 :(得分:2)

这些旧的一直很有趣。

每个线程1mb意味着你需要4-40gb,最低RAM和4k-40k核心。以及你有一个网络发送它的事实。

意味着它将在最近的交换机/路由器上的某个地方同步(大部分可能甚至在你的网卡上,如果你甚至可以同时获得所有的包,它设法发送它没有缓存或死在你身上)。意味着所有工作多线程都是无用的,因为它不会同时到达端点。

把它想象成一条40'000车道的道路并在其上放置40,000辆汽车,确保每个人同时到达道路上的同一点,但随后他们离开公路回家。每个人都会在不同时间回家,即使他们在同一时间点开始在40公里的道路上行驶。

你只是,不能,击败物理领域(还......)。