qt';当从外部对象调用方法时,gui线程会在引擎盖下生成线程吗? 我在开发一个基于Qt的C++应用程序时,遇到了一个线程/内存问题,我正在寻找一个正确的解释。我真的不能发布一个功能完整的示例,因为它需要链接到Qt等。但是这个问题在几行简短的文字中得到了非常清楚的解释

qt';当从外部对象调用方法时,gui线程会在引擎盖下生成线程吗? 我在开发一个基于Qt的C++应用程序时,遇到了一个线程/内存问题,我正在寻找一个正确的解释。我真的不能发布一个功能完整的示例,因为它需要链接到Qt等。但是这个问题在几行简短的文字中得到了非常清楚的解释,c++,multithreading,qt,scope,C++,Multithreading,Qt,Scope,当我单击gui上的按钮时,会发生如下情况: void MainWindow::onClick(){ std::vector<int> vec; vec.push_back(0); dev.connect(vec); // do some more stuff } 我遇到的问题是,设备驱动程序向我抛出异常,因为它们从vec中获取了错误的值。事实上,当我进入connect时,数据就消失了:在这个范围内vec是空内存。我使用shared\u ptrs

当我单击gui上的按钮时,会发生如下情况:

void MainWindow::onClick(){

    std::vector<int> vec;
    vec.push_back(0);

    dev.connect(vec);

    // do some more stuff
}
我遇到的问题是,设备驱动程序向我抛出异常,因为它们从
vec
中获取了错误的值。事实上,当我进入
connect
时,数据就消失了:在这个范围内
vec
是空内存。我使用
shared\u ptr
s解决了这个问题

我的理论是,当我从GUI线程调用
dev.connect(vec)
时,Qt实际上将该调用放在一个单独的线程上。然后,该函数需要很长时间,Qt决定是时候继续并完成
onClick
(或者类似的事情,可能会立即发生),因此当
vec
Device::connect
中处理时,它已经超出了范围。考虑到
shared_ptr
在这里节省了时间,这一点很合适


所以我的问题是,我说的对吗?有人能解释Qt隐式线程行为的细节吗,或者指出一些这样的解释

您要问的是,QT ui线程是否可能在某些任务中花费太长时间,以致于它被中断,从函数返回,然后尝试从停止的位置恢复

答案是否定的。如果一个线程被中断,那么它要么返回到原来的位置,要么即将终止。否则的话,病毒扫描器很可能会对其进行标记,并引入令人讨厌的bug

如果您尝试在UI线程中执行一些需要很长时间的操作,那么可能发生的情况是您的UI变得无响应,并且操作系统会抱怨应用程序变得无响应(因为应用程序不再能够对操作系统发送给它的事件做出响应)

更有可能的是,当一个信号在QT中被提升时,无法保证它会立即传递到插槽,因此您将以您所描述的情况结束


shared_ptr“节省时间”这一事实意味着您不会看到这样的情况,即您正在破坏堆栈(一件好事,它们很难调试);一个简单的堆栈跟踪应该可以回答您的问题。

加上一个到UKMonkey,因为答案确实是“否”。谢谢你提供的细节

进一步调查后,我发现实际上还有另一个问题一直是设备驱动程序投诉的核心。我认为这是向量的问题,因为(在这个特殊情况下)空向量可能是异常的根,调试器将其显示为空。使用
shard_ptr
s,我看到了向量中的值,但仍然有异常。然后,我找到了异常的(不相关且真实的)原因并修复了它。返回到非共享的_ptr版本(但不相关的异常抛出错误被压扁),代码按预期运行


所以,这一切只是一个骗局。但是,我很高兴我知道答案是“不”。在处理像这样的简单场景时,Qt在线程方面没有做任何有趣的事情。我显示的代码确实阻止了对
connect

的调用,我相信它确实产生了(Qt专用)线程。您可以通过调试器(Linux上
pthread\u create
上的断点)找到答案。对于GTKQt来说也是一个类似的问题,它会执行一些隐式线程,但在这种情况下不会影响您-主窗口的对象实例的onClick信号和插槽位于同一个对象上,因此发送/接收qt信号将在同一个线程上完成(除非您专门传递了qt::Blocking/QueuedConnection)。您的设备类是否派生自QObject?如果是这样,请检查您没有隐式调用超类的QObject的connect()函数。您的vec在哪一点超出范围?我假设您的最后一个vec.push()和dev.connect(vec)之间的汇编代码足够短,可以提供答案。绝对不,Qt从来不会代表您做出这样的决定,而是关于在GUI线程中执行繁重工作的文档。相反,他们鼓励您(使用Qt的开发人员)使用Qt。像这样的事情永远不可能隐式完成,因为它总是会有非常糟糕的副作用(正如你在问题中提到的)……我真的不能发布一个功能完整的示例,因为它需要链接到Qt等
void Device::connect(const std::vector<int>& vec){
    // do some stuff with vec that takes a long time
}