我们能否在PC上创建并运行一个包含300,000个线程的C#应用程序?

7
我正在尝试模拟300,000个消费者访问服务器的情景。因此,我正在通过从并发线程中重复查询服务器来创建伪客户端。
但首先要克服的障碍是,在PC上是否可能运行300,000个线程?这里有一段代码,我正在使用它来查看最初可以获得多少最大线程,然后再用实际函数替换测试函数:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace CheckThread
{
    class Program
    {
        static int count;

        public static void TestThread(int i)
        {
            while (true)
            {
                Console.Write("\rThread Executing : {0}", i);
                Thread.Sleep(500);
            }
        }

        static void Main(string[] args)
        {
            count = 0;
            int limit = 0;
            if (args.Length != 1)
            {
                Console.WriteLine("Usage CheckThread <number of threads>");
                return;
            }
            else
            {
                limit = Convert.ToInt32(args[0]);
            }
            Console.WriteLine();
            while (count < limit)
            {
                ThreadStart newThread = new ThreadStart(delegate { TestThread(count); });
                Thread mythread = new Thread(newThread);
                mythread.Start();
                Console.WriteLine("Thread # {0}", count++);
            }

            while (true)
            {
                Thread.Sleep(30*1000);
            }
        } // end of main
    } // end of CheckThread class
} // end of namespace

现在我尝试的可能有些不切实际,但是如果有解决方法并且您知道,请帮助我。


2
看起来是 https://dev59.com/BXVC5IYBdhLWcg3w7Vxq 的重复。 - holtavolt
5
如果你所说的“run”是指在线程之间来回切换…… 呵呵 - Richard Brightwell
很抱歉我没有说明目的。我的设置是服务器-客户端设置。我想强调的是客户端而不是服务器。在这个设置中,进程向正在运行的客户端进程提出请求,客户端进程将转发请求到服务器进行服务。但我们都明白,将这么多线程创建在一台机器上是不切实际和不推荐的。此外,我想要给客户端造成压力并且希望这些线程每分钟至少执行一次的动机似乎过于迫切了!:( - Andy_MSFT
5个回答

6
每个线程都会创建自己的堆栈和本地存储,对于32位操作系统,每个线程大约需要512k的堆栈空间,我认为64位操作系统的堆栈空间是32位的两倍。简单的电子表格计算得出,对于您的300k客户端,我们有146.484375 GB的堆栈空间。
因此,请不要创建300k个线程,而是使用线程池模拟300k个请求,虽然说实话,我认为最好的方法是通过网络接口让几个测试客户端向服务器发送垃圾数据。
有很多网页负载测试工具可供选择。一个很好的起点是:http://www.webperformance.com/library/reports/TestingAspDotNet/

4
您可以通过调用ThreadPool.SetMaxThreads方法来更改最大线程数。300,000个线程可能会让您的电脑爆炸*。
*这可能有些夸张。

这与问题无关,因为他没有使用线程池。 - Sven
1
可能有点夸张,但他需要大约300GB的内存才能将那么多线程保存在内存中。 - Alex Moore

3

无关语言的答案:

更好的方法可能是使用反应器模式,每个核心最多使用1或2个并发线程。


如果您想使用反应器模式,这个链接可能会有所帮助:http://www.robertsindall.co.uk/blog/the-reactor-pattern-using-c-sharp/ - Robs

1

由于 .Net 为每个 CLR 线程分配整个堆栈(1MB),正如 Ben 所说,你的电脑可能会爆炸。或许会遇到 OoM 问题。


0

你试图创建300K个线程的测试结果如何?我不会在我的电脑上尝试!

无论如何,你也无法一次连接300K个客户端,因为单个服务器上没有足够的套接字可用(因此需要分流)。

我进行了一些服务器测试,并通过调整注册表以使更多的套接字可用,将24K个套接字连接到一个服务器上,全部在一个盒子上。这是我预期的结果,因为服务器<>客户端连接需要每端一个套接字对象,而只有64K个套接字可用。我没有尝试创建24K个线程进行测试,而是使用了一个客户端线程类,在多个客户端套接字对象列表中打开/关闭连接。

敬礼, 马丁


实际上,坦率地告诉你,我甚至无法接近那个标记!我按间隔增加了线程数。所以我达到的最大线程数约为5k。 - Andy_MSFT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接