![]() |
1
16
我将着重讨论这两种方法之间的差异。没有一个通用的答案适用于所有的用例,所以很好地理解它们是什么来选择最适合您的用例。 使用moveToThread()移动线程() 用于控制 对象的线程关联 ,这基本上意味着设置线程(或者更好的qt事件循环),对象将从中发出信号并执行其插槽。 如您链接的文档所示,这可以用于在不同的线程上运行代码,基本上创建 假工人 ,编写要在 公用插槽 (在示例中 嫁妆() 插槽),然后使用 移动线程 将其移动到不同的事件循环。 然后,连接到该插槽的信号被触发。因为发出信号的物体 控制器 在示例中)位于不同的线程中,并且信号通过排队连接连接到我们的DoWork方法,DoWork方法将在工作线程中执行。 关键是你正在创建一个 新事件循环 ,由工作线程运行。因此,一旦Dowork时隙启动,整个事件循环将一直忙到退出,这意味着传入信号将排队。 子类化qthread()qt文档中描述的另一种方法是对qthread进行子类化。在这种情况下,可以重写qthread::run()方法的默认实现,该方法创建一个事件循环,以运行其他内容。 这种方法本身没有什么问题,尽管有几个陷阱。 首先,编写不安全的代码非常容易,因为 () 方法是该类中唯一将在另一个线程上实际运行的方法。 例如,您在构造函数中初始化了一个成员变量,然后在 () 方法,则在调用方的线程中初始化成员,然后在新线程中使用。 对于任何可以从调用方调用或在run()内部调用的公共方法来说,情况都是一样的。 同时,插槽将从调用方的线程执行(除非您做了一些非常奇怪的事情 移动线程(此) )导致额外的混乱。 所以,这是可能的,但你真的是靠自己的方式,你必须格外注意。 其他方法当然,这两种方法都有其他选择,这取决于您需要什么。如果在运行gui线程时只需要在后台运行一些代码,可以考虑使用 QtConcurrent::run() . 但是,请记住qtconcurrent将使用全局 qthreadpool线程池 . 如果整个池都很忙(意味着池中没有可用的线程),您的代码将不会立即运行。 另一种选择,如果你至少在C++ 11上使用的是较低级别的API,比如 std::thread . |
![]() |
2
8
作为出发点:两者都不要。在大多数情况下,您有一个希望异步运行的工作单元。使用
如果有一个对象对事件做出反应和/或使用计时器,则它是
这样的对象还可以包装阻塞api。
子类别化
|
![]() |
3
3
qthread是低级线程抽象,首先看高级api QtConcurrent 模块和 QRunnable 如果这些都不适合你,那就读 this old article ,它告诉您应该如何使用qthread。将线程和在此线程中执行的任务看作一个单独的对象,不要将它们混合在一起。 因此,如果需要编写自定义的、特定的或扩展的线程包装器,那么应该将qthread子类化。 如果qobject派生类具有信号和插槽,则在其上使用moveToThread。 在其他情况下,使用qtconcurrent、qrunnable和qthreadpoll。 |
![]() |
4
0
简单的回答总是。 将对象移动到线程时:
当你分类的时候
qt博客对该问题有完整的描述: Youâre doing it wrong⦠.
请记住,默认情况下,当从其他线程对象发送信号时,插槽会尝试在线程之间跳转。有关详细信息,请参阅 Qt::ConnectionType |
![]() |
user107586 · 如何处理等待句柄不会导致无限循环? 6 月前 |
![]() |
ron burgundy · 获取-释放语义是否跨线程传递?[副本] 6 月前 |
![]() |
BenjiFB · C#内存缓存:在一次操作中追加到列表? 6 月前 |
![]() |
András Takács · Python多线程问题 10 月前 |
|
András Takács · Python多线程错误 10 月前 |