有一CListCtrl控件m_listCtrl,有一工作线程用于从串口接收数据并显示在m_listCtrl上,每10S刷新一次数据。(主线程)从菜单栏选择某一子菜单,子菜单的内容(已经保存的接收到的历史数据文件)也是显示在m_listCtrl上。如果某一时刻选择某一个菜单子项,正好遇上接收到的数据显示的时刻,则程序会死掉。菜单显示和串口数据刷新使用的代码不同,二者分开实现。
    尝试过事件等待和互斥变量都无法解决此问题,比如说互斥量时,我是将请求互斥量WaitForSingleObject和释放互斥量ReleaseMutex分别放置于显示代码的前后(见附代码)。
或许是解决问题的思路不对有或许是我对线程同步的处理不正确,比如同步代码放置的地方不对。WaitForsingleObject(m_hSynMutex, INFINITE);
LoadFile();//该函数菜单选择时显示数据
ReleaseMutex(m_hSynMutex);
WaitForsingleObject(m_hSynMutex, INFINITE);
switch(Code) //该switch用于接收串口收据刷新
{case 1:
...
default:
break;
}
ReleaseMutex(m_hSynMutex);另:串口接到的是一个数据包,经过一个循环然后与switch条件配对显示再m_listCtrl中。

解决方案 »

  1.   


    谢谢各位同行的热心~
    程序的其他地方没有问题的,10S刷新一次的数据是在线程中进行,只有在主线程与工作线程同时对m_ListCtrl进行操作时才出现卡死的问题。我以为它是线程不能同步造成的,我的理解是主辅线程都同时对资源m_ListCtrl进行竞争,所以才出现了这个问题?
    各位能不能给我解释下这为什么不是线程同步的问题呢,而是什么问题呢?我的理解看来是出问题了。还有我的问题解决了,就是通过发消息的方式:工作线程接收到来自串口的数据包,将该数据包保存到一个全局变量中然后给主线程发消息,在响应函数里对数据包进行处理并显示。
      

  2.   

    一般UI操作都是用主线程操作,工作线程不参与UI。。
      

  3.   

    工作线程中发送自定义消息到UI线程,UI线程的消息处理函数去更新界面控件信息
      

  4.   

    不需要设置全局变量,SendMessage里Wparam或lparam都可以传递数据呀.
      

  5.   

    PostThreadMessage,发送消息的函数很多。SendMessage和PostMessage是有区别的。
      

  6.   

    工作线程和主线程共享一个对象
    对象形如以下:class SerialData //数据条目容器
    {
    public:
      DataNode &GetData(int pos);
      void AppendData(DataNode &data);
      ...
    private:
      DataNode m_Data[...]; //数组形式, 可改为链表形式或干脆使用STL来做容器impl
      RWLocker m_Locker; //读写锁, 用于同步
    }
    class DataNode //用于存放数据条目
    {
    public:
      inline void SetId(int id) {m_nId = id;}
      inline int GetId() {return m_nId;}
      ...
    private:
      int m_nId;
      ...
    }然后再在容器中加锁
    最好使用ReadWriteLocker类型的锁, 可在很多地方获得rwlocker的实现源码
    当串口数据到达时, WriteLock, 这时拒绝一切其它线程读写
    当需要刷新或需要对数据进行枚举时, ReadLock, 这时允许一切读操作, 但禁止写操作
      

  7.   

    曾经往LIST中添加数据全是在线程中实现,没见有什么问题!
    不过还是建议在主线种中更新界面,线程中拿到数据后保存,然后发消息给窗口就好了
      

  8.   

    请问用SendMessage里Wparam或lparam的两个参数怎么传递参数呢?假如我的工作线程从串口中收到一个数据包pData,然后SendMessage(WM_UPDATEDATA,False);在主线程的OnUpdateList中对这个数据包进行处理?利用Wparam或lparam,怎么将参数传过来啊?
      

  9.   

    在wParam或lParam中可以传数据包的地址