我们可以在 C# 应用程序中创建 300,000 个线程并在 PC 上运行吗?
我试图模仿 300,000 个消费者正在访问服务器的场景。因此,我尝试通过从并发线程重复查询服务器来创建伪客户端。
但首先要克服的障碍是,PC上是否可以运行30万个线程?这是一个代码,我最初用它来查看可以获得多少个最大线程,然后用实际函数替换测试函数:
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
现在我正在尝试的可能是不切实际的,但是如果有办法的话这样做你就知道了,然后请帮助我。
I am trying to imitate a scenario where 300,000 consumers are accessing a server. So I am trying to create the pseudo clients, by repeatedly querying the server from the concurrent threads.
But the first hurdle to be cleared is, whether it is possible to run 300,000 threads on a PC? Here is a code which I am using to see intially how many max threads I can get, and later then replace the test function with the actual function:
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
Now what I am trying might be unrealistic, but still, if there is a way out to do it and you know, then please help me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
每个线程都会创建自己的堆栈和本地存储,在 32 位操作系统上,您会看到每个线程大约有 512k 的堆栈空间,我认为堆栈空间在 64 位操作系统上会加倍。快速回顾一下电子表格计算结果,我们可以为您的 30 万客户提供 146.484375 GB 的堆栈空间。
所以,不,不要创建 300k 线程,而是使用线程池来模拟 300k 请求,尽管说实话,我认为您最好使用多个测试客户端通过网络接口向您的服务器发送垃圾邮件。
有很多可用的网络负载测试工具。好的起点:http://www.webperformance.com/library/reports/TestingAspDotNet/
Each thread will create its own stack and local storage, you are looking at roughly 512k of stack space per thread on a 32bit OS, I think the stack space doubles on a 64 bit OS. A quick back of the spreadsheet calc gives us 146.484375 gigs of stack space for your 300k clients.
So, no, don't create 300k threads, but rather use the threadpool to simulate 300k requests, although tbh I think you would be better off with several test clients spamming your server through a network interface.
There are a lot of web load-testing tools available. Good starting point : http://www.webperformance.com/library/reports/TestingAspDotNet/
您可以通过调用 ThreadPool 来更改最大线程数。 SetMaxThreads 方法。 300,000 个线程可能会让你的电脑爆炸*
*这可能有点夸张
You can alter the maximum nunmber of threads by calling the ThreadPool.SetMaxThreads method. 300,000 threads will probably make your PC explode*
*This is probably an exaggeration
与语言无关的答案:
解决此问题的更好方法可能是使用 Reactor 模式,每个核心最多有 1 或 2 个并发线程。
Language-agnostic answer:
The better way to probably go about this is using the Reactor pattern, with a maximum of 1 or 2 concurrent threads per core.
由于 .net 为每个 clr 线程提交整个堆栈 (1MB);正如本所说,你的电脑实际上可能会爆炸。或者可能是 OoM。
As .net commits the entire stack (1MB) for each clr thread; as Ben says, your PC may actually explode. Or possibly OoM.
那么,当您尝试创建 300K 线程时,您的测试结果是什么?我不会在我的身上尝试!
无论如何,您无法一次连接 300K 个客户端,因为单个服务器上没有足够的可用套接字(因此是农耕)。
我已经做了一些服务器测试,通过调整注册表以提供更多可用的套接字,我已经将 24K 套接字连接到服务器,全部是一个盒子。这在某种程度上是我所期望的,因为服务器<>客户端连接在每一端都需要一个套接字对象,并且只有 64K 套接字可用。我没有尝试为我的测试创建 24K 线程,我使用了一个客户端线程类,该类在列表中的多个客户端套接字对象上打开/关闭连接。
平均值,
马丁
Well, what was the result of your test when you tried to create 300K threads? I'm not going to try it on mine!
You could not connect up 300K clients at once anyway because there are not enough sockets available on a single server, (hence farming).
I have done some server testing and, by tweaking the registry to make more sockets available, I have had 24K sockets connected to a server, all one one box. That was somewhat what I was expecting since the server<>client connection requires one socket object at each end and there are only 64K sockets available. I did not attempt to create 24K threads for my testing, I used a client thread class that opened/closed connections on multiple client socket objects in a list.
Rgds,
Martin