日志
记录一次多线程出的问题
2017-11-20 16:48
工作时遇到一个bug:
1.项目简单介绍: 主要是车载系统,车上会用到蓝牙。 关于蓝牙的架构简单来说分为 蓝牙模块和UI。 蓝牙模块可以应对多个同平台项目,但是每个项目的UI都是不同的。这样可以在做多个项目时,只维护一份蓝牙模块代码。 蓝牙模块会更新蓝牙的状态给UI。(UI注册回调给模块,模块会调用那个回调) 2.大致更新策略就是: 1)蓝牙模块内部会有很多数据,每个数据对应一个ID。比如,hfp状态ID为2,蓝牙音乐状态ID为3,蓝牙电话本下载状态为4...... 2)数据变化时,模块把ID赋给一个notifyID的变量(先简单这么写吧) 3)模块调用UI注册进来的回调,UI去获取那个notifyID的值。 4)再分发下去做不同的处理。 问题: 蓝牙模块更新各个数据有可能会在多个线程里面同时进行。所以必须要保护notifyID。 模块更新函数伪代码:
这就意味着 Nothif_UI(ID) 这个函数里面不能执行比较耗时的东西,否则其他数据都会更新失败。 3.bug现象:在下载电话本时拨打电话,UI获取不到打电话的状态。所以界面显示不常了。等电话本下载完就不会出现问题了电话本下载策略:先下载电话本-》usleep(1000 * 1000) -》 下未接来电 -》 usleep(1000 * 1000) -》下已接来电 -》 usleep(1000 * 1000) -》 下外播电话 4.原因:在回调函数里面直接调用了下载电话本的函数,但是下电话本比较耗时。 下载过程更新播放状态一直失败 pthread_mutex_trylock这个函数失败了,返回值16. 5.解决方法:回调函数里面创建线程,让线程去下载。回调函数能及时返回。 6.总结: 1)多线程编程时要做好保护工作。 2)不能占有那个锁太久的时间。 3)上面的例子在更新冲突时,会把后更新的数据丢掉。这样是不合理的。可以用pthread_mutex_lock这个函数再加上超时机制。 |
下一篇: TCP 坚持定时器 保活定时器
上一篇: Linux基于Alsa的录音和播放程序