【问题标题】:Wake up QThread::exec() from another thread从另一个线程唤醒 QThread::exec()
【发布时间】:2014-06-03 20:09:29
【问题描述】:

考虑派生自 QThread 的 MyThread 并像这样实现它的 run() 例程

void MyThread::run() {
  QThread::exec();
}

或等效

void MyThread::run() {
  QEventLoop eventLoop(this);
  eventLoop.exec();
}

在这种状态下,如何通过另一个线程中的某些操作导致“执行”返回?

考虑相反的情况:如果没有轮询,如何将线程中的事件发布回主线程?

显然,从一个线程发出的信号在同一个线程中处理。

【问题讨论】:

    标签: c++ multithreading qt qthread qtcore


    【解决方案1】:

    您似乎对 QThreads 应该如何工作有一些误解。不幸的是,你并不孤单。

    首先要做的是阅读这里的正确用法:

    How To Really, Truly Use QThreads; The Full Explanation

    所以,你应该写的是这样的:

    QThread* thread1 = new QThread;
    QThread* thread2 = new QThread;
    Task1* task1 = new Task1();
    task1->moveToThread(thread1);
    Task2* task2 = new Task2();
    task2->moveToThread(thread2);
    connect(task2, SIGNAL(finished()), thread1, SLOT(quit()));
    connect(thread2, SIGNAL(started()), task2, SLOT(process()));
    thread1->start();
    thread2->start();
    

    如您所见,我正在使用 quit() 槽,就像前面提到的示例一样。您将需要在您的 task2 中使用 emit finished() 来尝试终止 thread1,反之亦然。

    【讨论】:

    • 为什么这个网站上的每个人都试图传播他们对“正确方式”TM 的想法,而不是实际回答问题?是编程,通常没有正确的答案,因为有多种处理问题的方法。即使这样的解决方案可能是您在为 nasa 构建某些东西时想要使用的解决方案,但如果您只想在五分钟内将某些东西拼凑在一起,然后再也不看它,它可能不是正确的解决方案。总而言之,是的,如果与他相关,请提供有关“正确方式”的链接,但也要回答所提出的问题。
    • 使用此模型是否可以从 线程 发出事件并在我的主线程中处理它们?
    • @TruthSerum:当然,请参阅示例中的此连接,connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));。
    • @chacham15:你知道我在不到两分钟的时间内就走对了吗?
    • @chacham15:我不明白为什么。对于包括我在内的许多人来说,它是如何设计的,是的,我更喜欢在帮助新人时使用正确的解决方案,而不是增加混乱。 ;-) 我很遗憾听到您不喜欢按照课程的含义来使用。
    【解决方案2】:

    QEventLoop 有一个可以调用的槽quit。如果您在 mythread 中引用了 eventloop,则可以使用它来调用插槽。

    信号/插槽可以交叉线程方式使用。更多信息在这里:Signals and Slots Across Threads

    QMetaObject::invokeMethod( eventloop, "quit", Qt::QueuedConnection)

    【讨论】:

    • 我已经测试过了。通过打印 QThread::currentThreadId() 我可以看到发出信号的线程也是处理信号的线程。这个答案对我没有帮助。 API 应该在 connect() 和 emit() 期间使用 QThread::currentThreadId() 来决定应该在哪里发布事件,但它似乎没有。
    • 那是假的,视情况而定。从文档本身:If the signal is emitted in the thread which the receiving object has affinity then the behavior is the same as the Direct Connection. Otherwise, the behavior is the same as the Queued Connection. 排队连接:The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. 请阅读我提供的链接。
    • EMIT 从线程执行:0x7f86dd5dc780 从线程处理执行:0x7f86dd5dc780
    • 您的测试代码有问题。我没什么好说的了。
    • 我认为这是因为我连接(this,SIGNAL,this,SLOT)和this==this。但是在哪里记录了正是这些指针控制了消息的传输方式?
    猜你喜欢
    • 2017-02-13
    • 1970-01-01
    • 2022-11-03
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    相关资源
    最近更新 更多