多线程问题

快乐乔巴 2012-04-24 01:26:22
最近学习多线程 遇到点问题
先看一段ConsoleApp程序吧
        static void Main(string[] args)
{
ThreadPool.SetMinThreads(100, 100);
ThreadPool.SetMaxThreads(100, 100);
Console.WriteLine("start...");
DateTime now = DateTime.Now;
for (int i = 0; i < 50; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(CallBack), null);
}

Console.ReadLine();
}

static void CallBack(object o)
{
Thread.Sleep(5000);
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("CurrentThreadId is {0}\n " +
"CompletionPortThreads is :{1}", a.ToString(), b.ToString());
Console.WriteLine(message);
}

这个程序很简单 就是先设置线程池最大最小都为100,然后循环50次线程 每个线程中的处理都睡眠5秒,由于提前设置了线程池最小线程是100, 所以程序结果所花费的时间差不多是5秒左右。

到这里我是明白的,下面测试Asp.net程序中的ashx (注意 这里ashx不是异步的Handler)
首先和上面一样在Global。asax中设置线程池最大最小都为100.
我在一个ashx中 同样写入ThreadPool.GetAvailableThreads来观察线程池中工作线程和I/O线程的使用情况,先测了一下,访问一次ashx 看输出结果线程池的工作线程少了几个 所以我认为访问ashx的时候也是调用线程池中的工作线程的。
那么我就满心欢喜的直接在测试ashx中的ProcessRequest方法里也写下睡眠5秒的处理
        public void ProcessRequest(HttpContext context)
{
System.Threading.Thread.Sleep(5000);
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("WorkerThreads is {0}\n " +
"CompletionPortThreads is :{1}", a.ToString(), b.ToString());

Debug.WriteLine(message);
}

既然都已经设置线程池最小为100了,那如果同时50次访问,应该和上面ConsoleApp程序一样是5秒左右。
可是我用测试软件模拟了50次 结果是第一次是花了18秒。。。 第二次趋于稳定是15秒左右 以后都是.
这是为什么呢???

ConsoleApp程序的线程池 和 Asp.net程序的线程池难道有区别??
先不考虑用异步Handler 大家先帮我看看到底哪里理解错了 那些多余花费的时间是什么?
请教大虾们哈


...全文
231 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qldsrx 2012-04-25
  • 打赏
  • 举报
回复
考虑网络上的延迟吧,这里用的TCP/IP协议,因此受到了半开连接数10的限制,不能很快建立50个连接,网络响应总有延迟的。
全局变量 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

没试过。
[/Quote]
++
铜臂阿铁木 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

进一步测试后 发现同时访问ashx 不是一次性就调用线程池50个线程 而是有间隔的 就感觉有点像在创建线程所在消耗的时间
但是我已经设置线程池最小为100了 然后我有测试了下 在ashx中加入了 ThreadPool.GetMinThreads 来查验是不是100
结果的确是100 也就是那个间隔并不是创建线程所消耗的时间 而且那个间隔很诡异 间隔时间不是均匀的
而且那个……
[/Quote]

单用线程之间的间隔,我估计不好测吧。
起码的ashx什么的装载也需要时间。

如果是我,我只看时间是否线性增长。
铜臂阿铁木 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

进一步测试后 发现同时访问ashx 不是一次性就调用线程池50个线程 而是有间隔的 就感觉有点像在创建线程所在消耗的时间
但是我已经设置线程池最小为100了 然后我有测试了下 在ashx中加入了 ThreadPool.GetMinThreads 来查验是不是100
结果的确是100 也就是那个间隔并不是创建线程所消耗的时间 而且那个间隔很诡异 间隔时间不是均匀的
而且那个……
[/Quote]

单用线程之间的间隔,我估计不好测吧。
起码的ashx什么的装载也需要时间。

如果是我,我只看时间是否线性增长。
cjh200102 2012-04-25
  • 打赏
  • 举报
回复
没试过。
anzhiqiang_touzi 2012-04-25
  • 打赏
  • 举报
回复
没遇到过
快乐乔巴 2012-04-25
  • 打赏
  • 举报
回复
还有人吗...
铜臂阿铁木 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

进一步测试后 发现同时访问ashx 不是一次性就调用线程池50个线程 而是有间隔的 就感觉有点像在创建线程所在消耗的时间
但是我已经设置线程池最小为100了 然后我有测试了下 在ashx中加入了 ThreadPool.GetMinThreads 来查验是不是100
结果的确是100 也就是那个间隔并不是创建线程所消耗的时间 而且那个间隔很诡异 间隔时间不是均匀的
而且那个……
[/Quote]

快乐乔巴 2012-04-24
  • 打赏
  • 举报
回复
进一步测试后 发现同时访问ashx 不是一次性就调用线程池50个线程 而是有间隔的 就感觉有点像在创建线程所在消耗的时间
但是我已经设置线程池最小为100了 然后我有测试了下 在ashx中加入了 ThreadPool.GetMinThreads 来查验是不是100
结果的确是100 也就是那个间隔并不是创建线程所消耗的时间 而且那个间隔很诡异 间隔时间不是均匀的
而且那个间隔不是一个线程一个线程之间的间隔 而是10几个线程之间
所以更加否定了是创建线程消耗的时间
。。。。
铜臂阿铁木 2012-04-24
  • 打赏
  • 举报
回复
系统的开销什么的吧。
IIS起码自己就那么大。

lz可以把sleep加大5秒。如果后来趋近于稳定在20秒,也就是线性增长,那可以确定是系统带来的开销了。
bdmh 2012-04-24
  • 打赏
  • 举报
回复
虽然没有研究过,不过感觉,这是http和本机winform程序的不同吧,不是代码问题,两种程序依托的运行环境不一样
快乐乔巴 2012-04-24
  • 打赏
  • 举报
回复
有些地方没说清楚 感觉 修正下
第二段代码中说的第一次18秒 意思是同时访问50次后 所花的时间
然后再测一下 就是第二次50次访问 是花了15秒
快乐乔巴 2012-04-24
  • 打赏
  • 举报
回复
第一个程序里的 有个地方写错了 不是CurrentThreadId 是WorkerThreads
string message = string.Format(CurrentThreadId is {0}\n " +
"CompletionPortThreads is :{1}", a.ToString(), b.ToString());
改成
string message = string.Format(WorkerThreads is {0}\n " +
"CompletionPortThreads is :{1}", a.ToString(), b.ToString());

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧