chongyong的个人主页

http://www.qtcn.org/bbs/u/184854  [收藏] [复制]

chongyong

  • 1

    关注

  • 0

    粉丝

  • 1

    访客

  • 等级:新手上路
  • 总积分:3
  • 男,1994-06-21

最后登录:2017-12-15

更多资料

日志

记录一次多线程出的问题

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
模块更新函数伪代码:
  1. void notify_data_ID(int ID)
    {
      ...
      pthread_mutex_trylock() // 加锁
      Nothif_UI(ID); // 这个函数会调用UI的函数
      pthread_mutex_unlock()
      ...
    }

这就意味着 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这个函数再加上超时机制。

分类:默认分类|回复:0|浏览:184|全站可见|转载
 

下一篇:

上一篇: Linux基于Alsa的录音和播放程序

Powered by phpwind v8.7 Certificate Copyright Time now is:12-18 01:15
©2005-2016 QTCN开发网 版权所有 Gzip disabled