c++ - 我可以将 QObject 的两个子类移动到同一个 QThread 吗?

标签 c++ multithreading qt qthread

我有两个 QObject 的子类:

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);

signals:

public slots:
    void process();
};

class ThreadController : public QObject
{
    Q_OBJECT
public:
    explicit ThreadController(QObject *parent = 0);
public slots:
    void sleep();
    void wakeUp();
private:
    QMutex *mutex;
    QWaitCondition *wc;
};

void ThreadController::sleep(){

    mutex->lock();
    wc->wait(mutex);
    mutex->unlock();
}

void ThreadController::wakeUp(){
    mutex->lock();
    wc->wakeOne();
    mutex->unlock();
}
******************************************************
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    QThread* thread = new QThread;
    Worker* worker = new Worker;
    ThreadController*controller=new ThreadController();
    controller->moveToThread(thread);
    worker->moveToThread(thread);

    QObject::connect(thread,&QThread::started,worker,&Worker::process);
    QObject::connect(&w,&MainWindow::wakeClicked,controller,&ThreadController::wakeUp);
    QObject::connect(&w,&MainWindow::sleepClicked,controller,&ThreadController::sleep);

    thread->start();
    return a.exec();
}

enter image description here

我将 worker 和 controller 移动到同一个 QThread。我想通过 ThreadController 控制线程(进入休眠或唤醒),而 worker 只是在做它的工作,现在这个想法行不通了,worker 可以执行进程但 Controller 不能工作,我不知道我的代码有什么问题。

最佳答案

谢谢@thuga 是的,就像你说的。 Worker::process 是一个无限循环:

void Worker::process(){

    int a=(int)QThread::currentThreadId();
    emit sendThreadId(a);
    int b=0;
    while (b<1000000) {
       b++;
       emit processResult(b);
       QThread::msleep(1);// signal emit too quickly will block the main thread,                 
                          //so i just let the loop slow down 
   }
}

为什么如果进程是无限循环,ThreadController::sleep 永远不会执行,但我测试过 ThreadController::wakeup 可以执行。 enter image description here

QObject::connect(&w,&MainWindow::wakeClicked,controller,&ThreadController::wakeUp,Qt::DirectConnection);

是的,直接连接让它工作。谢谢!我有一些问题:当 QThread 使用 QWaitCondition::wait() 时会停止其中的事件循环吗?那么任何发送到线程的信号都不会再被处理了?

我想在我的程序中重用QThread。当worker完成它的工作时会发送一个信号给controller,controller会执行sleep()函数。下次数据来的时候,controller wakeup()线程 worker 又去上类了。有没有其他解决方案适合这种情况?重用 QThread 或删除它并重新创建它(哪个性能损失更多)?

关于c++ - 我可以将 QObject 的两个子类移动到同一个 QThread 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38886969/

相关文章:

c++ - 从std::vector<bool>获取 boolean 引用

c++ - Boost.Spirit.X3如何防止token被之前的规则解析?

c++ - 通过解析纯文本文件生成数据结构

multithreading - 如何让OpenMP线程或任务在某个核心上运行

c++ - 错误 MSB6006 : "cmd.exe" exited with code 1 running QT application

c++ - 是否有一种简单的方法/算法来匹配 2 个 2D 点云?

c# - 奇怪的 InvokeRequired 问题

c - 使用原子和 futexes 锁定代码时无法找到竞争条件

qt - 在 QListView 的 QWidgetDelegate 的 paint() 方法中渲染 QWidget

c++ - 如何增加 QString 中的字符 (Qt)