您的位置:首页 > 其它

.net中的线程池肯定用了什么优化技术,和直接用线程差别巨大

2012-05-10 00:19 417 查看
由于现在很难用syn扫描,于是那天另做一个标准tcp扫描的时候发现了一个问题。

本来想象中很简单,就是一个多线程,一个tcpclinet而已。

扫描部分代码如下。多说一句,由于.net下无论tcpclient还是socket都没有connect timeout(连接超时)的设置,网上借鉴了一下别人的用AutoResetEvent的等待做超时,异步连接,如果超时之前连接成功就set(),如果等到100毫秒还没异步连接成功就认为失败。

private void ec(IAsyncResult iar)
{
try
{
TcpClient tc = (TcpClient)iar.AsyncState;
tc.EndConnect(iar);
are.Set();
}
catch { }
}
AutoResetEvent are = new AutoResetEvent(false);
private void ceshi(IPEndPoint ipp)
{
TcpClient tc = new TcpClient();
tc.BeginConnect(ipp.Address, ipp.Port, ec, tc);
are.WaitOne(100);
if (tc.Connected)
{
Console.WriteLine(ipp.ToString());
}
try
{
tc.Close();
}
catch { }
}

就这样一个同样的代码,我直接用Thread开512个线程去执行ceshi这个方法结果,几秒钟cpu100%了卡住了。我用vs2010性能分析工具,说全都是由于BeginConnect EndConnect和Close几个方法占用的cpu。

但是奇怪的是,同样还是上面的代码,用ThreadPool去执行ceshi,同样用512的线程的话,cpu占用率就基本为0,不要怀疑线程池的限制了线程数,我ThreadPool.SetMaxThreads(int.MaxValue, int.MaxValue);了

而且从netstat -ano看,确实是大量的连接,确实是512个线程连接,从路由器中看也是如此。

难道线程池还能优化TcpClient?真是百思不得其解啊。

顺便说一下,如果直接用Thread 512个线程的话,从任务管理器中看,上来就会有512个线程(其实还有一些辅助线程上来600多),而用线程池的话,他会从几十个线程开始2个2个的往上加,最后也达到600多个,稳定到600多线程,保证512个线程去连接是没有问题的。

所以上来说一下,做这种大量网络操作的同志们还是用线程池吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: