Ida*_*n K 6 c++ qt multithreading qthread
在我的应用程序中有主线程和工作线程(QThread).
从主线程我想调用我的工作线程的方法,让它在线程的上下文中运行.
我已经尝试使用QMetaObject::invokeMethod并给它QueuedConnection选项,但它不起作用.
我也尝试从主线程(连接到工作线程的插槽)发出信号,但也失败了.
这是我尝试的大致的片段:
class Worker : public QThread
{
Q_OBJECT
public:
Worker() { }
void run()
{
qDebug() << "new thread id " << QThread::currentThreadId();
exec();
}
public slots:
void doWork()
{
qDebug() << "executing thread id - " << QThread::currentThreadId();
}
};
Run Code Online (Sandbox Code Playgroud)
使用QMetaObject方式:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main thread id - " << QThread::currentThreadId();
Worker worker;
worker.start();
QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
使用信号方式:
class Dummy : public QObject
{
Q_OBJECT
public:
Dummy() { }
public slots:
void askWork() { emit work(); }
signals:
void work();
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main thread id - " << QThread::currentThreadId();
Worker worker;
worker.start();
Dummy dummy;
QObject::connect(&dummy, SIGNAL(work()), &worker, SLOT(doWork()), Qt::QueuedConnection);
QTimer::singleShot(1000, &dummy, SLOT(askWork()));
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
两种方式都会导致主线程ID被打印出来QThread doWork.
此外,我想实现一个简单的生产者 - 消费者,但如果这有效,是否有任何理由不这样做?
问题在于接收者(QThread)“存在”于主线程中,因此主线程的事件循环是执行该槽的事件循环。
来自 Qt 的文档:
对于排队连接,当控制返回到对象所属线程的事件循环时,将调用槽。槽在接收者对象所在的线程中执行。
所以到目前为止我找到的解决方案是在线程的 run() 内部创建一个对象并使用它的插槽。这样,接收者的所有者就是线程,然后在线程上下文中调用槽。