2011-08-15 21 views
0

我有一个高速渲染应用程序,我想输出日志消息到单独的窗口。该应用程序是多线程的,并且在任何给定时间,所有线程都可能有记录。日志消息到窗口,游戏应用程序

我已经在使用控制台输出,而且工作正常!

我所做的是:

  • 创建的LogMessage队列
  • 当一个线程有话要说,它锁定的队列,并插入其消息放入队列
  • 一个“刷新“线程睡觉,直到某些线程记录一些东西(在任何线程上调用log()唤醒刷新线程),其作业是将所有日志消息刷新到文件和控制台。

这对文件和控制台日志记录都正常工作:似乎都不关心他们正在接收打印调用的线程与应用程序的主线程不同。但是,any other window you create does care。所以现在当我尝试打印到我创建的separate RichText window时,冲洗线程不起作用。

所以这是令人失望的。现在唯一的解决方案是将刷新线程代码移动到主线程(与运行渲染循环的主线程相同),这意味着显示帧时可能存在很长的延迟(如果等待锁定日志队列所以他们可以输出),我不想要。

回答

0

好像你有什么看起来像你的同花线程冲突:

  • 这是一个工作线程,即希望能够当没有工作可做睡觉 - 有可能使用上的WaitForSingleObject一个事件句柄

  • 但是,如果线程创建一个窗口,它现在需要表现为一个GUI线程 - 这意味着它不允许阻塞或等待,而是必须返回到消息循环(GetMessage/TranslateMessage/DispatchMessage),当它完成它的工作。要解决这个明显的冲突

一种方法如下:

  • 使用MsgWaitForMultipleObjects:这基本上是一个版本的WaitFor的......这将唤醒如果事件被触发,如果有一条消息需要处理,那么您使用GetMessage()等进行处理,完成后返回MsgWaitFor ...并重新开始,等待事件或GUI消息。它允许线程既是GUI线程也是工作线程。

另一种方法(这很可能是更多的工作,我觉得上面的一个更可能更适合你现有的代码 - 但提到这一点,无论如何)如下:相反

  • 具有工作线程通过使用WaitForSingleObject进入睡眠状态,利用它是GUI线程的事实;它有效地通过调用GetMessage()来结束睡眠,并且如果另一个线程向它发送消息则会唤醒。这需要拥有一个线程拥有的可以发布消息的隐藏窗口。 (你也可以使用PostThreadMessage来避免创建一个隐藏的窗口,但是它有一些棘手的问题,如果线程显示一个消息框或对话框时消息看起来会“迷路”,所以隐藏窗口是最安全的方法)。