【问题标题】:How to pass Windows Messages from one thread to another?如何将 Windows 消息从一个线程传递到另一个线程?
【发布时间】:2019-09-16 03:53:38
【问题描述】:

我正在编写一个控制台游戏引擎。其中的游戏循环在单独的线程函数中处理:

hThread = CreateThread(
        NULL,
        0,
        &_GameThread,
        _self,
        0,
        &dwThreadID);

WaitForSingleObject(hThread, INFINITE);

_GameThread() 本身现在只包含一个简单的while(1)。很简单。

我需要以某种方式管理游戏中的控件,因此我选择了制作消息窗口的方法,它将按下的按钮转换为某个数组,然后由线程内的函数处理为某个动作(移动、转动等) .还做了一个函数,将消息传递到隐藏窗口:

int _DispMessage()
{
    MSG msg;
    int gResult;
    if(gResult = GetMessageW(&msg, 0, 0, 0) > 0) 
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return gResult;
}

没有线程这个函数可以正常工作,但是当游戏循环出来时,除了创建消息之外,没有收到来自内部的消息。所以问题是:如何使消息异步,以便我可以将键码推送到队列中,然后在游戏循环中检索它们?

我只有主进程,它执行引擎和一个线程。

【问题讨论】:

  • 更好的方法不是使用消息,而是使用同步原语(事件等)。
  • @MichaelChourdakis 我可以使用互斥锁或事件,但控件本身不会触发,我需要以某种方式管理按键,因此它们将是连续的,并且游戏循环中没有繁重的循环可能会减慢速度,并且控件本身不会持有线程
  • PostMessage() 将关键消息发送到另一个线程并使用另一个 getMessage 循环在那里检索它们。
  • @MartinJames 的主要问题是,它不会捕获任何消息。我做了一个 PeekMessage 循环,如果没有消息,它不会保持线程,但没有单个
  • @IlyaPakhmutov UI 窗口具有线程关联。只有创建窗口的线程才能接收该窗口的消息。要执行您的要求,您需要在游戏线程中创建一个(隐藏)窗口,以便您可以使用(Post|Send)Message() 向该窗口发布/发送消息。或者,使用PostThreadMessage() 将消息发布到线程本身。

标签: c multithreading winapi


【解决方案1】:

那是经典的Producer-Consumer problem。您可以在线查找实现示例。

基本思想是在主线程和将使用您的密钥代码的线程之间有一个共享内存数组。

当主线程访问数组时(即当您读取键码时),您使用互斥锁或信号量锁定数组。当键被添加到数组中时,锁被释放。

在消费者线程上,在尝试访问数组之前,您等待信号量/互斥锁被解锁,锁定它,从中消耗密钥,然后释放锁定。

请注意,目前的解决方案(在性能方面)比从主线程管理密钥要慢。当你锁定一个线程时,它基本上会停止工作,直到你解锁它。因此,如果您的消费者线程除了等待主线程之外没有工作,锁定/解锁、切换上下文等的成本将增加程序的开销。

【讨论】:

    猜你喜欢
    • 2016-09-09
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 2013-01-26
    相关资源
    最近更新 更多