背景
今天在工作中,遇到了很恼人的错误“double free or corruption”
,随着程序运行着,不一定何时就会出现,就像一颗定时炸弹,好气呀。网上找说是原因可能有两种:
- 字面意思,释放两次。不过这种错误太过低级,一般都不会犯;
- 内存越界也会报这个错误。比如访问了超过数组下表的元素。
在仔细查看程序过后,并没有发现上面的错误,我陷入了沉思。。。沉思过后终于发现问题所在:这是一个线程安全的问题!由于多线程之间用到了共享变量,同时读写却没有加锁,导致最后问题的产生。
项目内容
这个项目的大概内容是:与公安对接数据,主要是把机器人身上实时采集的数据实时的发送给公安那边的服务器,包括人脸图片、机器人状态、环境温湿度等… 由于需要在机器人内部传递数据并做处理再转发,这里用到了异步的“订阅–发布”模型。所有的发布者往消息总线上的话题发布消息,订阅者订阅需要的话题,以此来获取消息。
具体的流程图如下:
上面说到的每一个模块,上传人脸图片、机器人状态等,每个都是一个线程在工作。该线程首先订阅各自的话题,获取到要发送的信息内容,然后处理成json的可发送格式,再通过http协议发送过去。
分析
过程不难,但问题往往出现在看似简单的地方。就是由于我在多个线程中使用了同一个共享的全局变量,而且都对此变量进行了写操作,这些线程中都还没加锁,这就导致了错误的产生。
我猜是因为在一个线程刚把共享资源读取出来,还没有使用,另一个线程开始就把共享资源的内容改了,这样就可能导致资源的混乱?
线程同步的方法
rwlock
顾名思义,读写锁分为两种锁的操作:读锁和写锁