Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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
C++ 使用不同线程时Win32 API死锁_C++_Windows_Multithreading_Winapi_Showwindow - Fatal编程技术网

C++ 使用不同线程时Win32 API死锁

C++ 使用不同线程时Win32 API死锁,c++,windows,multithreading,winapi,showwindow,C++,Windows,Multithreading,Winapi,Showwindow,我在尝试从其他线程使用WIN32 API时遇到死锁。我的应用程序需要额外的线程来提高帧速率。但是,它实际上有助于我在几乎所有的系统功能中实现死锁: ::橱窗 ::移动窗口 ::更新窗口 例如,我知道ShowWindow()可能会被ShowWindowAsync()替换,它确实解决了这个问题,但是,MoveWindow()和UpdateWindow()中没有这样的替代方案 是否有人遇到过这些问题,解决方法是什么 谢谢 术语“死锁”描述了一种非常特殊的情况,即两个线程等待访问另一个线程锁定的资源。没

我在尝试从其他线程使用WIN32 API时遇到死锁。我的应用程序需要额外的线程来提高帧速率。但是,它实际上有助于我在几乎所有的系统功能中实现死锁:

::橱窗 ::移动窗口 ::更新窗口

例如,我知道ShowWindow()可能会被ShowWindowAsync()替换,它确实解决了这个问题,但是,MoveWindow()和UpdateWindow()中没有这样的替代方案

是否有人遇到过这些问题,解决方法是什么

谢谢

术语“死锁”描述了一种非常特殊的情况,即两个线程等待访问另一个线程锁定的资源。没有迹象表明在你的情况下(或是否存在?)正在发生这种情况,那么你到底在经历什么呢?另外,您希望通过多线程实现什么

在任何情况下,将UI保持在单个线程中,使用SendMessage()&Co将后台线程中发生的任何事件通知该线程。或者,您也可以使用计时器轮询某些状态更改。这样,您就安全了,您的应用程序不应该被锁定(至少不是因为使用来自不同线程的UI)


更准确地说,您必须将窗口及其所有子窗口的消息循环保持在一个线程中。您可以创建多个窗口,并从各自的线程处理每个窗口,但不要混合调用。但实际上,这种区别并不重要,因为很少有应用程序创建多个窗口(不,例如消息框或其他对话框不算在内)。

您提到的所有API函数都有一个共同点,即它们向目标窗口发送(!)一些消息。UpdateWindow可能是最明显的,因为它需要发送WM_PAINT。还要注意的是,它“发送”消息,而不发送到队列(对于UpdateWidow,MSDN文档会显式地调用它,对于其他文档,它可能不太明显)

还请注意,windows已在一些评论中提到。这意味着发送到该窗口的消息只在一个线程上接收/发送。如果将消息发送到另一个线程的窗口,操作系统将负责确定何时应发送该消息(即调用窗口过程)。这(发送传入消息)仅在某些API调用期间发生,在此期间,可以假定使用随机消息调用窗口过程是安全的。相关时间在GetMessage和PeekMessage*期间

因此,如果您的窗口拥有线程(也称为UI线程)正常地发送消息,那么传入的发送消息也会被快速调度。然而,从您的问题来看,您的UI线程当前很忙。如果第二个线程随后调用上述函数之一,那么它将阻塞,直到第一个线程提供发送消息的机会

正如其他人所说,将用户界面代码保存在一个专用UI线程上通常是一个好主意(尽管例外情况——一如既往——证明了这一规则)。而且(为了获得良好的用户体验),让拥有窗口的线程始终响应消息是绝对必要的。如果UI线程还必须等待某些同步对象,您可能会发现MsgWaitForMultipleObjects很有用


*列表可能不完整。

您在这些线程上使用过一些同步吗?信号量,互斥?(它们是否正在访问彼此的数据?)出于某种原因,主线程有时被称为
UI线程。UI操作最好在主线程中排队。虽然我不知道这在Windows中是否是致命的。第一个线程是否会发送消息?另请参见这个老问题User32是否是线程安全的,这是一个悬而未决的问题。像Raymond Chen这样的微软人会告诉你“是的,但窗口过程永远不会是线程安全的”。这是一种冗长的推卸责任和说“不”的方式。这永远不会有好的结局。重点关注在生成窗口内容的代码中使用线程。这才是真正的减速所在。因为这是您的全部代码,所以更容易获得正确答案。非常感谢您的回答。不幸的是,在我的例子中,将所有内容都保存在一个线程中并不是那么简单,因为我正在为另一个应用程序编写插件,而另一个应用程序选择从另一个线程调用窗口。无论您的体系结构的细节如何,附带的信息是:拥有窗口的线程需要输出消息。否则无法调用UpdateWindow之类的API。当然,您可以定义一些特定于WM_应用程序的消息,告诉窗口调整自身大小并将这些消息发布到队列中(我不是说这样的设计是可取的)