【发布时间】:2014-02-26 01:41:02
【问题描述】:
我编写了一款使用 ThreadPool 进行多线程处理的软件。
ThreadPool.SetMinThreads(128, 128);
ThreadPool.SetMaxThreads(512, 512);
for (int i = 0; i < 40; i++)
{
ThreadPool.QueueUserWorkItem(_ =>
{
Console.Write("!");
Thread.Sleep(1000);
Console.Write(".");
}, null);
}
在每个线程中,我执行阻塞网络操作(使用 http)。 围绕阻塞网络模型设计的软件,我无法转向非阻塞 1 线程 I/O。
它在 Windows 平台上完美运行,我可以在每个内核上使用 128-512 个线程,没有任何问题,一切正常。 但是当我转向单声道时,我看到了一些非常奇怪的行为。我不能让 mono 在每个 CPU 内核上运行多个线程,我可以得到的最大值 - 每个内核 1 个线程,这与我在 SetMinThreads/SetMaxThreads 中指定的内容无关。
在 Linux 下使用 .NET 4/4.5、MONO 版本 3.2.1 和我以前的系统上的一些旧版本进行了尝试。 顺便说一句,纯线程代码效果很好,例如这给出了预期的结果:
for (int i = 0; i < 20; i++)
{
var t = new Thread(_ => {
Console.Write("!");
Thread.Sleep(1000);
Console.Write(".");
});
t.Start();
}
【问题讨论】:
-
当然我可以重新发明轮子并编写自己的闪亮线程池,它会表现良好(基于最后的代码 sn-p)但它似乎很错误......这种单声道行为的原因是什么?
-
你应该使用异步http请求等。这样你就不需要很多线程来处理请求了。
-
512 个线程?!你知道开销有多大吗?如果你不介意我问,你为什么要使用这么多线程?
-
让我指出,使用大量线程是合法的。如果你有一个现有的应用程序,如果可以避免的话,你不会重写它。你调高线盘。它是一种提高吞吐量的非常省力的工具。如果这足以实现您的目标,那么您将在一分钟内完成。
-
也就是说,您正在将线程池自动缩放与 IO 绑定任务一起使用。这不起作用,因为线程池不知道正确的并行度。到目前为止,您的方法很可能不是最理想的。
标签: c# mono threadpool