我有一个程序需要用到到线程,用循环建立多线程,但是线程数很大,有四五千个多线程,每个线程用时短的只有半秒,多的需要3-5秒,只要用来等待网络传回的数据,不会占用很多CPU时间。大概是这样的:
string[5000] arr;
for(i=0;i<5000;i++)
{
  System.Threading.WaitCallback waitCallback = new WaitCallback ( MyThreadWork );
  ThreadPool.QueueUserWorkItem ( waitCallback, arr[i]);
}
public static void MyThreadWork ( object state ) 
{
string sIP = getIPaddr((string)state);
...
writetoDB(sIP);
...
}
问题是:怎么控制线程数在一个合适的数量,一下子建立500个线程可能会死机。

解决方案 »

  1.   

    你可以调用SetMinThreads和SetMaxThreads方法来限定最小线程数和最大线程数。
    建设我们设定最大线程数为50,那么按照你的代码,剩下的4950个请求都会处于等待状态,在同一时刻最多只有50个线程正在被执行。既然控制了当前并发运行的线程数量,那么CPU的使用率也能控制了,你就可以避免死机了。
      

  2.   

    获取当前系统进程  和你抢cpu的都干掉
      

  3.   

    顺便再问个问题,上面5000个线程中有大约一半需要使用下面的代码来写入acess数据库:
    OleDbCommand cmd = new OleDbCommand(sql, conn);
    cmd.ExecuteNonQuery();
    会不会存在数据库阻塞的问题??需不需要锁定数据库?
      

  4.   

    ThreadPool有个缺陷,当工作线程数量很大并且创建销毁非常频繁就会导致队列调度操作占用掉当前进程的绝大多数cpu,对线程要求非常高负载非常大的情况下尽量别用当前版本的ThreadPool,可以用Thread+Queue+Semaphore做一个针对自己应用的特殊thread pool。
      

  5.   

    我的程序是这样的,我要使用一个循环语句获取5000多个域名的IP地址,所以我想使用多线程来执行Dns.GetHostAddresses。我测试过如果有返回的域名,Dns.GetHostAddresses执行的时间很短,如果没有返回的域名,Dns.GetHostAddresses执行的时间就要很长了,可能有5秒都不止。获取域名后写入数据库。
    请大家帮忙看看,谢谢啦~~
      

  6.   


    那么请问高人,您的高见是什么呢?人家是在等待网络的返回,并不是楼主故意调用了Sleep。这个时候这些处于等待状态的函数调用栈类似于下面的状态ChildEBP RetAddr 
    00f4f13c 7c827d29 ntdll!KiFastSystemCallRet [d:\nt\base\ntos\rtl\i386\userdisp.asm @ 545]
    00f4f140 71b21af5 ntdll!NtWaitForSingleObject+0xc [d:\nt\base\ntdll\daytona\obj\i386\usrstubs.asm @ 2371]
    00f4f17c 71b2c507 mswsock!SockWaitForSingleObject+0x19d [d:\nt\net\sockets\winsock2\wsp\mswsock\msafdlib\proc.c @ 1792]
    00f4f1f4 71c02fee mswsock!WSPRecv+0x203 [d:\nt\net\sockets\winsock2\wsp\mswsock\msafdlib\recv.c @ 524]
    00f4f23c 64c0143c ws2_32!recv+0x83 [d:\nt\net\sockets\winsock2\ws2_32\src\recv.cpp 
    ......
    对于此类等待,你能做什么?自己设定一个超时时间,然后去Abort?如果ThreadPool的size过大,那么同时执行的线程数目会比较多,最终导致高CPU。
    所以为了避免高CPU,当然需要控制ThreadPool的大小了。