当从外部对象调用方法时,qt的gui线程会在引擎盖下产生线程吗?

时间:2017-11-30 13:55:09

标签: c++ multithreading qt scope

我最近在用c ++开发基于Qt的应用程序时遇到了线程/内存问题,我正在寻找正确的解释。我不能真正发布一个功能齐全的例子,因为这需要链接到Qt等。但问题很清楚地解释了几个短线。

当我点击gui上的按钮时,会发生类似这样的事情:

void MainWindow::onClick(){

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

    dev.connect(vec);

    // do some more stuff
}

在这种情况下,devMainWindow的成员,类型为Device,表示我想要连接的硬件(或更准确地说,硬件驱动程序)。 connect的代码类似于:

void Device::connect(const std::vector<int>& vec){
    // do some stuff with vec that takes a long time
}

我遇到的问题是设备驱动程序因为从vec中获取了错误的值而导致异常。事实上,当我进入connect时,数据就消失了:在那个范围内vec是空记忆。我使用shared_ptr s修复了问题。

我的理论是,当我从GUI线程调用dev.connect(vec)时,Qt实际上将该调用放在一个单独的线程上。然后,该函数需要很长时间,Qt决定是时候继续完成onClick(或类似的东西,可能会立即发生),以便在vec处理时{ {1}},它已经超出了范围。这符合Device::connect在这里节省一天的事实。

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

2 个答案:

答案 0 :(得分:1)

你要问的是,QT ui线程是否有可能在某个任务中花费这么长时间,它会被中断,从函数返回,然后尝试从它停止的地方恢复。

答案是否定的。如果一个线程被中断,那么它将返回到它的确切位置,或者即将终止。尝试不这样做可能会被病毒扫描程序和标记器标记。引入令人讨厌的讨厌的错误。

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

更有可能的是,当QT中出现信号时,无法保证它会立即传递到插槽,因此您将最终处于您所描述的情况。

shared_ptr'节省了一天'的事实意味着你没有看到你正在破坏你的堆栈的情况(一件好事,他们很难调试);一个简单的堆栈跟踪应该回答你的问题。

答案 1 :(得分:0)

另外还有一个给UKMonkey,因为答案确实是“没有”。谢谢你的详细信息。

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

所以,这只是一个红鲱鱼。但是,我很高兴我知道答案是事实&#39;不是。在处理像这样的直接场景时,Qt并没有做任何有趣的线程业务。我展示的代码确实阻止了对connect的调用。