为什么 beginthreadex 线程参数变量在父线程中没有更新
Why is beginthreadex thread argument variable not updating in parent thread
我有一个线程,它创建了一个隐藏窗口,用于根据电源状态接收 WinAPI 消息。我需要从线程中获取创建的窗口的HWND
,以便我可以抛出一条WM_QUIT
消息来关闭窗口并优雅地结束线程:
主要:
HWND hiddenWindowHandle = NULL;
HANDLE PowerWindowThreadHandle = (HANDLE)_beginthreadex(0, 0, &windowsPowerThread, (void*)&hiddenWindowHandle, 0, 0);
线:
unsigned int __stdcall windowsPowerThread(void* data)
{
HWND hiddenWindowHandle = createHiddenWindow();
HWND hwHandle = *(HWND*)data;
hwHandle = hiddenWindowHandle;
...
问题是hiddenWindowHandle
未使用生成的HWND
进行更新。
我已经在线程中验证了它正在创建,并且我已经验证了在线程创建句柄之前我没有尝试访问句柄。
我在这里错过了什么?
您的代码缺少必要的同步。你在这里看到的是一场数据竞赛。因此,你得到的是严格未定义的行为。最有可能发生的是,编译器根本不会在循环的每次迭代中从内存中重新获取hiddenWindowHandle
的值,因为它可以简单地假设该值不会更改。一种可能的解决方案是使hiddenWindowHandle
成为std::atomic
,并让主线程执行繁忙的等待,直到值从NULL
更改。或者,您可以将对共享变量的所有访问放入由互斥锁锁定的关键部分中,或使用条件变量等待值可用。
根据评论进行编辑:
因此,如果我正确理解您的代码,则创建窗口的线程将以void*
的形式接收指向结果变量的指针,然后尝试像这样传达结果:
unsigned int __stdcall windowsPowerThread(void* data)
{
…
HWND hwHandle = *(HWND*)data;
hwHandle = hiddenWindowHandle;
…
}
这里有两个问题。首先,data
不指向HWND
,它现在指向一个std::atomic<HWND>
,所以你已经在那里有未定义的行为。主要问题,以及可能解释为什么你的原始代码无论如何都不能正常工作,尽管存在数据竞争,是你创建了一个名为hwHandle
的新本地HWND
。此局部变量使用data
指向的任何值进行初始化。然后,将结果分配给该局部变量,但永远不会分配给实际结果变量。
你想做的更多的是类似的东西
unsigned int __stdcall windowsPowerThread(void* data)
{
…
HWND hiddenWindowHandle = createHiddenWindow(…);
*static_cast<std::atomic<HWND>*>(data) = hiddenWindowHandle;
…
}
您可能还需要考虑使用std::thread
而不是原始 CRT 函数。
- 发出信号以从线程更新 UI
- 为什么 beginthreadex 线程参数变量在父线程中没有更新
- Modal QprogressDialog从Worker线程更新
- 从另一个线程更新QT小部件的一种详细方法
- 从其他std ::线程更新QT GUI
- 从工作线程更新QtCharts的正确方法
- C++从异步线程更新窗口
- 线程更新全局指针时对全局指针的影响
- 从其他线程更新QT图形视图
- 从线程更新进度条的最佳方式
- 如何允许工作线程更新 X11 窗口
- Gtkmm : 如何从另一个线程更新 UI?不断
- 从多个线程更新命令行 printf 信息
- 如何从未创建该窗口的线程更新该窗口
- 按线程更新 QT
- 如何从另一个线程更新列表视图
- 从聚合线程更新QListView会使GUI卡住
- 从不同的线程更新GUI
- 从运行QML QtQuick2引擎的不同线程更新c++模型的行为
- 线程更新类对象