我在程序中开了两个线程:一个是主线程用来显示和交互,另外一个是监听线程,用来检测输入的变化。由于输入的数据非常多,为了防止数据丢失,我使用了两个缓冲区。首先用一个接收数据,当收到任何一个数据以后就向主线程投递一个消息,主线程处理这个消息时将该缓冲区交给主线程分析,而通知监听线程用另外一个缓冲区取数。当主线程处理完毕以后,通过投递消息告诉监听线程,这样监听线程就可以将主线程处理期间所收到的数据再次投递一个消息,重复上述的步骤。可是这里需要解决消息投递的问题PostMessage异步方式中,当收到数据后,监听线程需要检查主线程的消息队列中是否存在之前投递的消息,如果存在则不能够重复投递消息。否则由于数据变化太快,导致消息队列中全部都是这些消息,不能够正常处理别的事件了,甚至于当外界数据停止变化时,主线程仍然在不停的处理之前投递的消息。这好像需要类似于WM_PAINT的消息产生机制,实现选择性发送或者消息的合并,当然也不像WM_PAINT消息那样优先级很低,只是不能反复发送它。还请大家帮帮忙,谢谢了!

解决方案 »

  1.   


    两个线程还是需要互相通知的吧。要不然显示线程怎么知道分析线程已经分析结束,而进行显示。而分析线程也不会知道显示线程已经刷新完毕,可以修改分析指针了啊?个人感觉要么通过异步的消息通知,要么通过程序查询的方法进行处理,而后者也需要对查询变量进行同步的。可是线程是为了实时分析的话,程序查询方法很不可取,因为可能一段时间内突发很多变化,而另外一端时间内却没有数据,而且很浪费CPU资源的。所以我通过Post消息来做的。可是当数据太快时,发现Post的消息太多了,消息队列充斥了这个消息,其实只要一个就够了。谢谢指导,请问有解决办法吗?目的是既不丢数据,又不导致系统性能严重的下降。
      

  2.   


    其实不是只放一个数据,是放很多的数据。只是假如主线程处理时间太长了以后,这个阶段内将会收到很多个数据,假设有N个吧。此时需要通知主线程N个消息。保证主线程可以处理它们。
    但是如果是有选择的投递消息,不到N个消息的话,请问有没有什么策略可以保证主线程不遗漏掉收到的数据,而且消息投递的次数最少?
    因为外界环境的不确定性,只能从最坏的方面打算了。即使主线程响应有所延迟也无所谓,因为放在消息队列中总能够显示的,可是数据的丢失却是不能容忍的。谢谢关注,请继续帮忙啊,谢谢
      

  3.   

    建立一个数据块队列,
    数据线程: 申请新内存->加入数据序列->缓冲区满后->从队尾插入,
    主线程:从队首取数据->分析处理->释放内存;建立一个CRITICAL_SECTION信号量
    用于插入和取出时的边界排斥量
      

  4.   

    建立一种类似缓存的机制 比如建立一个排序的表 包含已经投递过的消息
    向主线程投递消息前 先检查消息是否在这个区域中 没有则加入
    像这样
    class CCachedMsg
    {
    public:
     virtual bool HitTest();
    };
      

  5.   

    加个判断变量
    BOOL bProcessMsg = FALSE; // 是否处理了消息
      

  6.   

    谢谢大家,问题解决了!在接收线程中
    lock()
    bool exist = g_exist;
    unlock();
    if(!exist)
    {
      lock()
      g_exist = true;
      unlock();  PostMessage();  // 此时并不切换缓冲区
    }在主线程中响应消息
    OnMessage()
    {
      ASSERT(g_exist);  lock();
      // 取出所有接收到,但是尚未处理的数据,同时切换接收线程的缓冲区为空的(双缓冲),让它继续接收数据
      g_exist=false;
      unlock();  // 处理数据
    }这样一来消息队列中最多只有一个消息了,而且只要接收到数据一定会被处理,不会多投或者漏投消息。