本帖最后由 zhifu3158 于 2022-5-1 14:22 编辑
记二次:软件崩溃,异常代码:c000005 的处理办法和过程
上次写采集软件时遇到了崩溃问题: 记一次:软件崩溃,故障模块名称:ntdll.dll 的处理办法 https://bbs.125.la/forum.php?mod=viewthread&tid=14727649
这次是写多线程提交数据的软件也遇到了崩溃的情况,但这次不是 故障模块名称:ntdll.dll 而直接提示 异常代码:c000005 ... 如图:
事件起因:
这次写的是一个多线程(鱼刺线程池并发) 数据处理并post上传到网络服务器的软件,主要功能就是将本地数据进行大量的计算 替换 处理后上传!
事件现象:
在启动线程数大于40条时,软件运行一段时间(3-5小时)后会崩溃报错,不是绝对会报错:启动四个软件同时操作,有时会有一个、有时两个崩溃!会有至少一个崩!!!!
解决过程:
和上次的思路相同:https://bbs.125.la/thread-14727649-1-1.html
1、先度娘 异常代码:c000005 ...,这次悲催了,说啥的都有(系统问题、软件兼容、组件问题、甚至还有说变量内存问题如第一次故事)这次我无法确定问题所在了,最后从代码入手。
2、代码中最有可能出现的问题就是 多线程,但是软件还必须要多线程操作,为了长时间稳定运行而选择使用线程池方式(因为如果使用循环不断的启动大量的线程,内存很容易饱满溢出,线程池操作相对稳定,内存增长的比较少,不会因为内存爆满溢出)
经过反复思考代码中使用命令的逻辑性和函数的使用特性,(这是废话,意思就是说重点关注那些非易语言核心库命令和精易模块备注中有明确注意点的命令)
两次升级记录如下:
5.7.1 优化
1. 提取mx 网址中有一个有误 已经修改,
2. 文本_取中间_批量 去除函数中的 处理事件()命令,【因为多线程中尽量不要使用处理事件()】
5.7.2 优化
将 网页_访问_对象 改为 网页_访问 取消 COM库相关命令
结果: 5.7.1 依旧会崩溃。 5.7.2 三台电脑和vps 同时运行10多个小时无崩溃报错的情况,目前还算是稳定!
修改过程和思路如下:
线程池并发的软件也写过很多,但是像现在这样几个小时后软件崩溃的情况却很少遇到,所以线程池并发 的使用是没有问题的!很多地方也加了许可证,仔细查看代码发现有句读网络数据的URL地址有误,修改了, 其后面带有文本_取中间_批量 所以怀疑是调用 文本_取中间_批量 时提交的数据为空,可能会导致软件崩溃,查看其函数代码,发现提交空数据也没事,但是里面带有 处理事件() 这个删掉! 编译成5.7.1 运行四小时崩!
既然问题依旧,一时无语,继续看代码,发现有个子程序中少写了一句 线程_取消COM库 问题貌似找到了,因为com库的命令在精易模块中有特别备注:“有时执行线程的时候,会自动关闭,此时,可以在多线程的程序里创建COM对象前先初始化,一个线程只能调用一次” 。。。这个备注有点模糊,
“一个线程只能调用一次” 那线程内的子程序算什么?算作新的线程?使用的自定义命令中如果调用了 线程_初始化COM库 那是不是就造成了线程内多次调用了?多线程中涉及对象操作的时候必须要用,那软件不涉及对象操作也用上是否有坏处?在使用 网页_访问_对象 命令时肯定要初始化COM, 那如果多次调用呢?要多次初始化COM库是否有问题?毕竟你说 “一个线程只能调用一次” 我可以多次初始化并释放后再次初始化,但是如果代码写的不够谨慎,导致嵌套使用,是不是就会出现问题?还有为什么软件启动2条线程可以运行一天没问题,但是40条线程只能撑三五个小时?
论坛中有大佬专门讨论过COM库的问题:https://bbs.125.la/forum.php?mod=viewthread&tid=14015642&highlight=COM%E5%BA%93
可以确定在多线程中无节制的随意调用初始化COM库 会导致软件崩溃,而且不太支持高并发。那就好说了!
解决办法:在高并发线程中尽量少的使用 初始化COM 库命令,而且精易模块中的命令在 网页访问对象 编码对象 操作中已经添加了 初始化COM库的命令,如果你再使用com库命令,结果就是嵌套多次调用了。容易崩,
将网页_访问_对象 改为 网页_访问,(对象速度快,不是不能用,只是要谨慎些,还有关注编码对象、js等对象相关的操作)
修改后的软件 目前比较稳定(并发线程中保留了一条 网页_访问_对象() 命令,这个命令依旧在用,只是删除了程序中所有 COM库的相关操作)
有不足之处望大佬不吝指正!至于:“线程_初始化COM库 、 线程_取消COM库”在线程池该并发的应用还需要进一步测试。后期再补上测试结果、、、【对于易语言写的窗口应用来说,100条线程就算是高并发了,所以后面的测试注意是在100条线程内测试和内存使用情况】
【总结:】在使用精易模块中的:网页_访问_对象() 时,无需在前面使用 初始化com库命令,因为精易模块中已经加上了!总之在使用前尽量多看看精易模块的源代码!!
|