分享

并发调试:庄严

 海漩涡 2017-09-23


  当大并发上来时 可能会碰上多线程资源访问冲突类型的问题,比如该加锁的未加锁。这类问题往往你一单步跟踪,它就不出问题了。甚至并发的压力一小,也不出问题了。可是压力一大,又往往日志一片混乱。


处理这类问题,要学会几个常规的调试小窍门。

一、是记得为你的上层业务的网络报文,加一个全局唯一的id,比如一个uuid。回头出错时,可简单写个工具,从日志中挖出这个任务的独立的完整过程。


二、是,当然一些错误有时必须交叉看所有日志,反倒才有帮助是不是? 所以日志一定要有线程id,要有相关的socket连接编号,客户端的ip加端口加一个time_t通常可用作这个编号。还要有至少精确到毫秒的时间。如果问题逻辑居然跨多台主机(这不很常见吗?),现场搞台时间服务器 ,确保各台网络服务器至少在秒级上保持一致。难道许多看似穿越的bug,不是因为有太依赖时间的逻辑,可是有某主机停留在1970年的时光里造成的?


     还有,再强调下,一个好的log机制一定是调试多线程网络程序的基础工具。它至要保证,打到屏幕上或文件的日志,不会因为并发而混乱(就是保证一条日志输出的完整性,别夹杂另一条日志的部分),并且最好支持在屏幕上彩色显示,一定要有级别(信息,警告,错误,失败,调试,临时)控制,并且最好是可在运行期调换级别,一定要能方便地输出前面说的各类id及时间,最好也支持必要时依据当前调用的函数栈级自动处理缩进,还最好要有信息详细级别控制,也会有不想看线程id或时间的时候。


最后,一定要学会正确使用assert。该死就让它死,有利于找到问题,所有该自杀不自杀,非要带病运行的,都是作。因为c++多线程程序很调皮,它最喜欢让带病程序时好时抽。
最最后,当程序段错误了,一定要学会让留它下core文件,太多太多看似头大的问题,用gdb(或其它调试器)来个现场恢复,立刻水落石出。并且几乎都是并发问题。


最最最后,别忘了有tcptrace这样的工具,你的调试器再强,它也是只调一个节点上的一个网络相关进程,两个程序网络通信,到底是谁说错话呢?。用tcptrace中间一插手,清清楚楚,当然你不要程序逻辑还没正确,就开始上ssl追求安全。这也是一个必须的做法:你的要支持ssl的网络交互的实现,一定要实现成有可方便地切换回不带ssl的机制。

几个最后了?反正学个python,花点时间把你负责的网络模块的上下家,都写出来,当然不需要内部逻辑,只需要能互相喂数据,这样妈妈再也不用担心你自己测试不了自己的网络节点程序了,特别是当你的上家是一个猪一样的队友时,自行搞定上家的输出,简直是不加班的利器。py不会也没关系,用c++也可。如果上家是个纯粹的客户端,网上找找就有通用的。

又看了眼题目,发现自己的回答全是错的。因为这些恐怕都不是多线程网络程序的好的调试方法。好的调试方法就是不需要调试。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多