使用Qt线程的混乱

时间:2011-11-19 03:57:06

标签: c++ multithreading qt signals-slots qt-signals

因此,如果我理解正确,如果我有一个继承QObject的类FunctionsClass,我通过执行以下操作在FunctionClassThread的Qthread上设置该类:

FunctionsClass classObj; 
classObj.moveToThread( &FunctionClassThread );
FunctionClassThread.start();

根据我的理解,这种设置线程的方法只会处理FunctionsClass中插槽的执行,这意味着FunctionsClass中的插槽可以阻止运行FunctionsClass的线程由于某种原因有一个无限循环。

所以我的问题是:如何在线程上运行FunctionsClass的函数而不仅仅是插槽?有没有办法将整个对象(函数,成员变量等)放在一个线程上,以便仅从整个对象执行代码/数据?我是否理解线程如何处理插槽的执行是否正确?

2 个答案:

答案 0 :(得分:1)

执行对象的方法时,它会在您调用方法的线程中执行。 QObject的生活地点并不重要。

如果你想调用一个方法,使它在另一个线程中异步执行,你将不得不处理这种情况,以便发布消息,等待线程可用(可能很忙,它必须返回首先控制事件循环然后,运行方法。

这可以使用通常连接的信号和插槽来完成。如果您不想使用该机制,可以使用QMetaObject,但仍需将其声明为插槽。静态方法invokeMethod,如果使用Qt :: QueuedConnection调用,将调用拥有该方法的对象所在的线程中的方法。您还可以将参数传递给方法并从中返回值。

考虑到您希望能够从一个线程传递到另一个线程的任何数据类型需要在qRegisterMetaType注册,并且必须遵守其中报告的条件。

答案 1 :(得分:0)

类的方法将在调用它们的线程的上下文中执行。如果将QObject类移动到线程(让我们将其称为工作线程),那么只有从工作线程的run()方法直接(或间接)调用的该类的方法才会在工作线程的上下文。

如果你想从其他一些线程调用该类的方法,但仍然让它们在工作线程的上下文中运行,那么你需要一些方法来获取工作线程的消息,这样它就可以调用你的方法了想。这基本上是当穿过线程边界时由Qt信号和槽实现的。

通过大量的额外工作,还有另外两种方法可以做同样的事情。首先,QThread有一个事件循环,如果你不覆盖run(),它将默认启动。您可以创建可以发布到事件循环的custom events,它可以触发您的类中将在工作线程的上下文中执行的活动。

第二种方法是从另一个修改工作线程监视的类字段的线程调用类中的方法。您需要确保对任何这些字段的访问与某些机制(如互斥锁)同步。