两个一模一样的多线程程序,都是访问SQL数据库获得网页链接地址,然后用CHttpFile测试该链接地址是否有效,然后把结果的真假值写回SQL库。同样是开300个线程,程序A一切运行正常,更新了几十万的数据都没问题,把它开到1000个线程也没事。而程序B则随时都可能当机,注意是“当机”,机器重启了,不是程序挂了,连个错误都没报出来就直接重启了,连调试都没法做。线程开得越多,当的频率越高,搞不清是怎么回事。两个程序都是在线程中用ADO访问SQL,对公共的SQL连接加了临界段保护,并且在程序B中把网络连接的注释掉,只做数据库的读取和更新,程序也不会当掉。只要加上CHttpFile测试的就会当掉,而这个测试函数和程序A里面是一模一样的。A不会当,B却因为它当了,真是太太太奇怪了。后来把线程数开到30了还是会当掉,而程序A开1000都照跑不误。这是为什么???A和B唯一不同的地方就是网页链接地址的属性不同,A的是一些返回很快的网址,而B则是一些很慢的网址,经常会超时无法连上。但是异常都是用的一样的函数进行过了捕捉并且delete掉了。只是这么一点小小的不同造成两个程序如此大的差异,实在是头大,望高手解答解答。
建议减小线程数,A开1000,B开30,A没事,B当了换台机器试试。换过了,没用。
内存泄露。不是,内存在25M左右,不会涨个不停。
超时的处理,连接的超时已经SetOption设置了30秒,只连一次。最最不明白的是,怎么会重启机器,还没有碰到过,所以很很郁闷的。
这种情况很少见,一般是由于某种访问越界,而且是系统无法捕获的越界。 典型的情况是缓冲区或者字符串溢出。 记忆中好像只有 sprintf系列 的溢出bug能直接导致 重启机器(最新的vc版中都不建议使用sprintf系列函数了)。建议将重点放在 重启机器 这一现象上, 普通的bug、手段都不必考虑。因为这些bug都能被系统捕获处理,不会出现 直接 重启机器。可以考虑用 代码 拆分排除法, 笨点,但是能行。
不要用SetOption设置超时和重试次数-----没用,设不设都一样的,照样会重启。只要把程序里的SendRequest()注释掉也不会重启,可是程序A和B是一样的,SendRequest也是一样的。SendRequest就是发送HTTP头的函数,A没事,B当了。难道返回的响应信息会让机器当掉????????????还是SendRequest本身有问题?
同样是开300个线程,程序A一切运行正常,更新了几十万的数据都没问题,把它开到1000个线程也没事。而程序B则随时都可能当机,注意是“当机”,机器重启了,不是程序挂了,连个错误都没报出来就直接重启了,连调试都没法做。线程开得越多,当的频率越高,搞不清是怎么回事。-----------------------------------------------------------
开那么多线程干什么呀,没有必要吧!
微软msdn提倡,一个cpu对应一个工作线程,也有人提倡,工作线程数是cpu个数的2倍,所以,楼主搞那么多线程实在没有必要,线程频繁切换,浪费了资源,还降低了处理速度。建议楼主先把线程数降下来,其实windows线程数不是无限大的,只能支持一两千个线程。
实际上你开了上千个线程,已达windows 极限了,完全没必要开那么多。你可以使用系统线程池,降低线程数。
把CHttpFile测试去掉会出现吗?
把程序rebuild all一遍再说!
〉而B则是一些很慢的网址,经常会超时无法连上。
有没有测试在AB使用相同的网页链接地址的属性的时候,B还会当机么
写日志的时候,信息要详细一些,比如,时间,线程ID,调用的函数名等,便于调试。
Thanks all...........就此结帐。问题不解决总是不甘心,可是现实往往不是自已能左右。。