gpt4 book ai didi

c++ - 在 QThread 的上下文中调用方法

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:26:11 24 4
gpt4 key购买 nike

在我的应用程序中有主线程和工作线程 (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();
}
};

使用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();
}

使用信号方式:

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();
}

这两种方式都会导致在 QThread doWork 中打印主线程 ID。

另外,我想过实现一个简单的生产者-消费者,但如果可行,有什么理由不这样做吗?

最佳答案

问题在于接收器(QThread)“存在于”主线程中,因此主线程的事件循环是执行槽的事件循环。

来自 Qt 的文档:

With queued connections, the slot is invoked when control returns to the event loop of the thread to which the object belongs. The slot is executed in the thread where the receiver object lives.

所以到目前为止我找到的解决方案是在线程的 run() 中创建一个对象并改为使用它的槽。这样接收器的所有者就是线程,然后在线程上下文中调用槽。

关于c++ - 在 QThread 的上下文中调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1216588/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com