使用 Qt 线程的混乱
因此,如果我理解正确,如果我有一个继承 QObject 的类 FunctionsClass
,并且我通过执行以下操作在名为 FunctionClassThread
的 Qthread 上设置该类:
FunctionsClass classObj;
classObj.moveToThread( &FunctionClassThread );
FunctionClassThread.start();
根据我的理解,此方法设置线程只会处理 FunctionsClass
中插槽的执行,这意味着运行 FunctionsClass
的线程如果由于某种原因,FunctionsClass 具有无限循环。
所以我的问题是:如何在线程上而不只是插槽上运行 FunctionsClass 的函数?有没有办法将整个对象(函数、成员变量等)放在线程上,以便仅执行该整个对象中的代码/数据?我对线程如何处理插槽执行的理解是否正确?
So if I understand correctly, If I have a class FunctionsClass
that inherits QObject and i set that class up on a Qthread called FunctionClassThread
by doing:
FunctionsClass classObj;
classObj.moveToThread( &FunctionClassThread );
FunctionClassThread.start();
From what I understand this method of setting up a thread will only handle the execution of slots in the FunctionsClass
, which means the thread running FunctionsClass
can be blocked if a slot in FunctionsClass
for some reason has a infinite loop.
So my questions are: How can I run the functions of FunctionsClass on a thread not just the slots? Is there a way to place a whole object (functions, member variables, etc) on a thread for execution of code/data from that whole object only? And is my understanding of how the thread will handle the execution of slots correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您执行对象的方法时,它会在您调用该方法的线程中执行。 QObject 位于何处并不重要。
如果你想调用一个方法,以便它在另一个线程中异步执行,你必须处理这种情况,以便发布消息,等待线程可用(可能很忙,它必须将控制权返回给首先是事件循环),然后运行该方法。
这可以使用信号和槽以及通常的连接来完成。如果您不想使用该机制,可以使用 QMetaObject,但是您仍然必须将它们声明为插槽。静态方法invokeMethod,如果使用Qt::QueuedConnection 调用,将在拥有该方法的对象所在的线程中调用该方法。您还可以将参数传递给该方法并从中返回值。
考虑到您希望能够从一个线程传递到另一个线程的任何数据类型都需要使用 qRegisterMetaType 并且必须遵守其中报告的条件。
When you execute a method of an object it is executed in the thread you're invoking the method. It doesn't matter where the QObject is living.
If you want to invoke a method so that it is executed in another thread asynchronously you'll have to handle the situation so that the message is posted, waits for the thread to be available (might be busy, it has to return control to the event loop first) and then, run the method.
This can be done using signals and slots, with the usual connection. If you don't want to use that mechanism, you can use QMetaObject, but you still have to declare those as slots. The static method invokeMethod, if called with Qt::QueuedConnection will invoke the method in the thread in which the object owning the method is living. You can also pass arguments to the method and returns values from it.
Consider that any data types you want to be able to pass from a thread to another need to be registered with qRegisterMetaType and must respect the conditions reported in there.
类的方法将在调用它们的线程的上下文中执行。如果将 QObject 类移动到线程(我们将其称为工作线程),则仅从工作线程的 run() 方法直接(或间接)调用该类的方法,将在工作线程的上下文中执行。
如果您想从其他线程调用该类上的方法,但仍然让它们在工作线程的上下文中运行,那么您需要某种方法来向工作线程获取消息,以便它可以调用您想要的方法。这本质上就是跨越线程边界时 Qt 信号和槽所实现的。
如果需要做大量额外的工作,您还可以通过其他两种方法来完成同样的事情。首先,
QThread
有一个事件循环,如果您不重写run()
,则默认情况下会启动该事件循环。您可以创建可以发布到事件循环的自定义事件这可以触发类中将在工作线程上下文中执行的活动。第二种方法是从另一个线程调用类中的方法来修改工作线程监视的类字段。您需要确保对任何这些字段的访问都与某种机制(如互斥体)同步。
Methods of a class will execute in the context of the thread that calls them. If you move a QObject class to a thread (let's refer to it as worker thread), then only methods of that class that are called directly (or indirectly) from the
run()
method of the worker thread, will execute in the context of the worker thread.If you want to call methods on that class from some other thread, but still have them run in the context of the worker thread, then you need some way to get a message to the worker thread so it can call the method you want. This is essentially what is achieved by Qt signals and slots when thread boundaries are crossed.
With a lot of extra work, there are two other ways you can do the same thing. First,
QThread
s have an event loop which is started by default if you don't overriderun()
. You can create custom events that you can post to the event loop which can trigger activity in your class that will execute in the context of the worker thread.The second way would be to call methods in your class from another thread that modify class fields that the worker thread monitors. You need to be sure that access to any of these fields is synchronized with some mechanism like a mutex.