Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading winapi线程在消息传递工作之前需要时间初始化?_Multithreading_Winapi_Messages_Timing - Fatal编程技术网

Multithreading winapi线程在消息传递工作之前需要时间初始化?

Multithreading winapi线程在消息传递工作之前需要时间初始化?,multithreading,winapi,messages,timing,Multithreading,Winapi,Messages,Timing,我有一个按顺序创建线程的主程序: ThreadB那么 ThreadA(传递给ThreadB的ID) 使用CreateThread函数 线程A使用PostThreadMessage向线程B发送消息。 B使用GetMessage获取消息 我遇到的问题是,PostThreadMessage在第一次调用时会随机阻塞,并且永远不会返回,有时程序运行正常,有时运行程序,在第一次PostThreadMessage时,它会以0 CPU使用率阻塞。然而,如果我在第一条PostThreadMessage之前将Sle

我有一个按顺序创建线程的主程序: ThreadB那么 ThreadA(传递给ThreadB的ID) 使用CreateThread函数

线程A使用PostThreadMessage向线程B发送消息。 B使用GetMessage获取消息

我遇到的问题是,PostThreadMessage在第一次调用时会随机阻塞,并且永远不会返回,有时程序运行正常,有时运行程序,在第一次PostThreadMessage时,它会以0 CPU使用率阻塞。然而,如果我在第一条PostThreadMessage之前将Sleep(10)添加到ThreadA,我似乎从未遇到过这个问题


关于线程和消息的计时,我遗漏了什么?

在线程具有消息队列之前,您无法向线程发送消息。只有在该线程调用函数(如
GetMessage
PeekMessage
)时,才会创建消息队列。睡眠所做的是将发送线程延迟足够长的时间,以便接收线程调用
GetMessage
并设置其消息队列


顺便说一句,我强烈建议不要使用
PostThreadMessage
,因为这些消息可能会丢失。最好在接收线程上创建一个仅消息窗口(其父线程为
HWND\u message
),然后将消息发送给该线程。

在线程具有消息队列之前,不能将消息发送给该线程。只有在该线程调用函数(如
GetMessage
PeekMessage
)时,才会创建消息队列。睡眠所做的是将发送线程延迟足够长的时间,以便接收线程调用
GetMessage
并设置其消息队列


顺便说一句,我强烈建议不要使用
PostThreadMessage
,因为这些消息可能会丢失。最好在接收线程上创建一个只显示消息的窗口(带有
HWND\u message
)并将消息发送到该窗口。

要添加到Anthony Williams的正确答案中,我用来处理此问题的代码如下所示。我有一个类似MyThread的课程

void MyThread::Start()
{
  m_hResumeMain = CreateEvent(NULL,FALSE,FALSE,NULL);
  m_hThread = CreateThread(NULL,0,ThreadProc,this,0,&m_dwThreadId);
  WaitForSingleObject(m_hResumeMain,INFINITE);
  CloseHandle(m_hResumeMain);
  m_hResumeMain=0;
}

DWORD MyThread::ThreadProc(LPVOID pv)
{
  MyThread* self = (MyThread*)pv;
  return self->ThreadProc();
}

DWORD MyThread::ThreadProc()
{
   MSG msg;
  // Create the thread message queue
  PeekMessage(&msg,0,0,0,PM_NOREMOVE);
  // Resume the main thread
  SetEvent(m_hResumeMain);
  while(GetMessage(&msg,0,0,0)>0){
    if(msg.hwnd){
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    else {
     DoThreadMessage(&msg);
    }
  }
  return 0;
}

问题的症结在于,您最终无法依靠
睡眠
来保证工作线程得到充分初始化。另外,一般来说,在允许启动线程恢复之前,工作线程需要完成的工作量通常很小。因此,在创建线程之前创建一个事件对象,在主线程上等待它,并在初始化完成后在工作线程上发出信号。

要添加到Anthony Williams的正确答案中,我用于处理此问题的代码如下所示。我有一个类似MyThread的课程

void MyThread::Start()
{
  m_hResumeMain = CreateEvent(NULL,FALSE,FALSE,NULL);
  m_hThread = CreateThread(NULL,0,ThreadProc,this,0,&m_dwThreadId);
  WaitForSingleObject(m_hResumeMain,INFINITE);
  CloseHandle(m_hResumeMain);
  m_hResumeMain=0;
}

DWORD MyThread::ThreadProc(LPVOID pv)
{
  MyThread* self = (MyThread*)pv;
  return self->ThreadProc();
}

DWORD MyThread::ThreadProc()
{
   MSG msg;
  // Create the thread message queue
  PeekMessage(&msg,0,0,0,PM_NOREMOVE);
  // Resume the main thread
  SetEvent(m_hResumeMain);
  while(GetMessage(&msg,0,0,0)>0){
    if(msg.hwnd){
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    else {
     DoThreadMessage(&msg);
    }
  }
  return 0;
}
问题的症结在于,您最终无法依靠
睡眠
来保证工作线程得到充分初始化。另外,一般来说,在允许启动线程恢复之前,工作线程需要完成的工作量通常很小。因此,在创建线程之前创建一个事件对象,在主线程上等待它,并在初始化完成后在工作线程上发出信号