我有一个程序需要用到到线程,用循环建立多线程,但是线程数很大,有四五千个多线程,每个线程用时短的只有半秒,多的需要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个线程可能会死机。
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个线程可能会死机。
建设我们设定最大线程数为50,那么按照你的代码,剩下的4950个请求都会处于等待状态,在同一时刻最多只有50个线程正在被执行。既然控制了当前并发运行的线程数量,那么CPU的使用率也能控制了,你就可以避免死机了。
OleDbCommand cmd = new OleDbCommand(sql, conn);
cmd.ExecuteNonQuery();
会不会存在数据库阻塞的问题??需不需要锁定数据库?
请大家帮忙看看,谢谢啦~~
那么请问高人,您的高见是什么呢?人家是在等待网络的返回,并不是楼主故意调用了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的大小了。