【问题标题】:Windows Api Multi-threading MessagesWindows Api 多线程消息
【发布时间】:2012-11-28 20:11:54
【问题描述】:

我只是好奇如何在不使用 Windows API WaitFor* 函数的情况下实现多线程,该函数会停止程序直到线程返回。如果线程阻止主应用程序调整大小或移动等,那么使用线程有什么意义?

是否有任何形式的带有线程的 Windows 消息传递,这将允许我调用我的线程函数然后返回,并在线程完成运行时处理线程的返回值?

【问题讨论】:

  • 调用/返回不是线程间通信的合适术语——线程不能被调用也不能返回。使用您的操作系统和 GUI 实现提供的适当的线程间通信。在 Windows 上,这将是 SendMessage(),或者最好是 PostMessage()。不要试图等待 GUI 事件处理程序 - 这不是 GUI 线程的设计方式!

标签: c++ multithreading winapi


【解决方案1】:

如果您希望您的 UI 线程知道任务线程何时完成它的任务,那么您可以让您的任务线程向您的主窗口发布(自定义 - WM_USER 及更高版本)消息(连同线程 ID 和句柄)。并且主窗口的window proc可以知道一个特定的任务线程已经完成了它的任务。这样,UI 线程就不必在线程对象上主动等待(使用 WaitFor*)。

【讨论】:

  • +1 - 发布消息是与 GUI 线程通信的经典方式。
【解决方案2】:

您可以使用MsgWaitForMultipleObjectsEx 等待线程完成并同时处理消息。

【讨论】:

  • 使用 MsgWaitForMultipleObjectsEx 方法要注意的一点是,当必须添加新任务线程时,必须中止等待并使用新添加的句柄创建新数组 - 然后应该重新调用等待-发布。此外,总可等待句柄限制为 64 个。
【解决方案3】:

看看 std::thread、boost::thread、just::thread,对于 c++ 的一般多线程。

但是关于 Windows 消息传递 win32 和 MFC,MSDN 明确声明 它不是多线程,它是单线程。 (如果使用多线程,则会出现未定义的行为)

对于在主应用程序窗口线程之外的其他线程中发出的异步消息,您应该使用::PostMessage(),它将在单线程窗口的单线程消息泵中插入消息事件。

【讨论】:

  • 再次。为 PostMessage API +1。
  • 嘿,感谢 msgs 的家伙 - 我已经为我的线程实现了一个独特的 GUID 注册消息。但我对“单线程”这个概念很好奇。我假设在上面这意味着消息传递总是发生在所有窗口都可以访问的单个线程中?
  • 并不是说“所有窗口都可以访问”这个线程,实际上一个进程的所有窗口都只由主窗口/应用程序线程管理。这是一个人问什么是消息泵social.msdn.microsoft.com/Forums/en-US/winforms/thread/… 的链接,而这个是消息队列系统的介绍msdn.microsoft.com/en-us/library/windows/desktop/…
【解决方案4】:

WaitForSingleObject 可以是非阻塞的,只需传递零超时作为第二个参数:

// Check is thread has been finished
if(::WaitForSingleObject(threadHandle, 0) == WAIT_OBJECT_0)
{
   // Process results
   ...
}

您需要定期检查此情况,例如在计时器上或在消息循环中处理任何消息之后。

或者您可以使用MsgWaitForMultipleObjectsEx。当调用线程消息队列中发生一些消息/输入事件时,它会解除阻塞并返回。

正如其他答案所提到的,还有另一种方法 - 使用 Windows 异步发布消息来表示线程已完成其工作。这种方式有缺点 - 工作线程必须知道要向其发布消息的目标窗口或线程。这种依赖性使设计复杂化,并引发了有关检查线程/窗口生命周期的问题。为了避免它消息广播(PostMessage(HWND_BROADCAST,...)) 可以使用,但是对于你的情况来说这有点大材小用了,我不推荐。

【讨论】:

    猜你喜欢
    • 2010-12-11
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 2012-08-02
    • 2011-03-13
    • 2017-06-10
    相关资源
    最近更新 更多