两个一模一样的多线程程序,都是访问SQL数据库获得网页链接地址,然后用CHttpFile测试该链接地址是否有效,然后把结果的真假值写回SQL库。同样是开300个线程,程序A一切运行正常,更新了几十万的数据都没问题,把它开到1000个线程也没事。而程序B则随时都可能当机,注意是“当机”,机器重启了,不是程序挂了,连个错误都没报出来就直接重启了,连调试都没法做。线程开得越多,当的频率越高,搞不清是怎么回事。两个程序都是在线程中用ADO访问SQL,对公共的SQL连接加了临界段保护,并且在程序B中把网络连接的注释掉,只做数据库的读取和更新,程序也不会当掉。只要加上CHttpFile测试的就会当掉,而这个测试函数和程序A里面是一模一样的。A不会当,B却因为它当了,真是太太太奇怪了。后来把线程数开到30了还是会当掉,而程序A开1000都照跑不误。这是为什么???A和B唯一不同的地方就是网页链接地址的属性不同,A的是一些返回很快的网址,而B则是一些很慢的网址,经常会超时无法连上。但是异常都是用的一样的函数进行过了捕捉并且delete掉了。只是这么一点小小的不同造成两个程序如此大的差异,实在是头大,望高手解答解答。

解决方案 »

  1.   

    应该还是同步的问题。SQL的读取和更新都加了保护了,不可能把临界段加到SendRequest里去,那样就和单线程没什么区别了。
    建议减小线程数,A开1000,B开30,A没事,B当了换台机器试试。换过了,没用。
    内存泄露。不是,内存在25M左右,不会涨个不停。
    超时的处理,连接的超时已经SetOption设置了30秒,只连一次。最最不明白的是,怎么会重启机器,还没有碰到过,所以很很郁闷的。
      

  2.   

    >>重启机器
    这种情况很少见,一般是由于某种访问越界,而且是系统无法捕获的越界。 典型的情况是缓冲区或者字符串溢出。 记忆中好像只有 sprintf系列 的溢出bug能直接导致 重启机器(最新的vc版中都不建议使用sprintf系列函数了)。建议将重点放在  重启机器 这一现象上, 普通的bug、手段都不必考虑。因为这些bug都能被系统捕获处理,不会出现 直接 重启机器。可以考虑用 代码 拆分排除法, 笨点,但是能行。
      

  3.   

    我的建议是:不要用SetOption设置超时和重试次数等,就用系统默认的。
      

  4.   

    sprintf系列函数重启------程序原来用的CString的Format,后来改成用sprintf结果都是一样的,都会重启机器。
    不要用SetOption设置超时和重试次数-----没用,设不设都一样的,照样会重启。只要把程序里的SendRequest()注释掉也不会重启,可是程序A和B是一样的,SendRequest也是一样的。SendRequest就是发送HTTP头的函数,A没事,B当了。难道返回的响应信息会让机器当掉????????????还是SendRequest本身有问题?
      

  5.   


    同样是开300个线程,程序A一切运行正常,更新了几十万的数据都没问题,把它开到1000个线程也没事。而程序B则随时都可能当机,注意是“当机”,机器重启了,不是程序挂了,连个错误都没报出来就直接重启了,连调试都没法做。线程开得越多,当的频率越高,搞不清是怎么回事。-----------------------------------------------------------
    开那么多线程干什么呀,没有必要吧!
    微软msdn提倡,一个cpu对应一个工作线程,也有人提倡,工作线程数是cpu个数的2倍,所以,楼主搞那么多线程实在没有必要,线程频繁切换,浪费了资源,还降低了处理速度。建议楼主先把线程数降下来,其实windows线程数不是无限大的,只能支持一两千个线程。
    实际上你开了上千个线程,已达windows 极限了,完全没必要开那么多。你可以使用系统线程池,降低线程数。
      

  6.   

    CHttpFile测试影响到了性能?
    把CHttpFile测试去掉会出现吗?
    把程序rebuild all一遍再说!
      

  7.   

    开那么多线程干什么呀,没有必要吧!------>实际运行中线程都会在SendRequest那里等待服务器的回应,300个线程其实切换线程不是很频繁,因为有的链接响应可能很慢,那么这个线程基本就是在那暂停,这样运行时间长后,大多数的线程都是处于等待状态的。rebuild all一遍再说!--》clean----rebuild all了N次,没用。CHttpFile测试去掉会出现吗?----》不会出现当机,但是程序A和B的CHttpFile的测试是一样的,一模一样COPY过去的。A不当,B会当。所以才觉得郁闷。看看日志写到哪里当机的---》试过,作用不大,300个线程是处于无序竞争的,共享的一个数据库当前记录号ID.也就是说有的线程运气好,链接回应的快,那么它在数据库里的记录号就要大,而运气背的线程记录号就小,写到日志的话也不知道倒底是谁出了毛病,那怕就10个的话也看不清楚。因为就不知道是那些跑的快的线程出的问题还是那些跑得慢的出的问题。建议线程数先搞小--->也试过,也会当掉,只不过是运行时间长一点,因为线程少,测试的链接数也少。启动和故障恢复”设置一下--》这个还没听说过,明天试试看。其实当机还算是比较好的情况,有的时候这处程序一当掉会把.h或者.cpp给做掉,里面一堆乱码,害得当时还重写了一遍,结果还是这种现象。这个任务当时在重启了十多遍机器后,在C盘多了十多个Found file文件夹之后,总算是把数据库扫完了。只是这个BUG没找到,很是不甘心。。
      

  8.   

    〉A和B唯一不同的地方就是网页链接地址的属性不同,A的是一些返回很快的网址,
    〉而B则是一些很慢的网址,经常会超时无法连上。
    有没有测试在AB使用相同的网页链接地址的属性的时候,B还会当机么
      

  9.   

    看看日志写到哪里当机的---》试过,作用不大,300个线程是处于无序竞争的,共享的一个数据库当前记录号ID.也就是说有的线程运气好,链接回应的快,那么它在数据库里的记录号就要大,而运气背的线程记录号就小,写到日志的话也不知道倒底是谁出了毛病,那怕就10个的话也看不清楚。因为就不知道是那些跑的快的线程出的问题还是那些跑得慢的出的问题。-------------------------------------------------------------
    写日志的时候,信息要详细一些,比如,时间,线程ID,调用的函数名等,便于调试。
      

  10.   

    最近为了装VS2005,格了系统,数据库也没了,测试不了了。而且老板最近要求做另一个东西,也没时间来测了,谢谢各位的回复。
    Thanks all...........就此结帐。问题不解决总是不甘心,可是现实往往不是自已能左右。。