Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QThread-调用另一个线程的方法_C++_Multithreading_Qt_Signals_Slot - Fatal编程技术网

C++ QThread-调用另一个线程的方法

C++ QThread-调用另一个线程的方法,c++,multithreading,qt,signals,slot,C++,Multithreading,Qt,Signals,Slot,我正在尝试使用invokeMethod调用另一个线程的方法,而不是Main。不幸的是,这会使应用程序在尝试执行invokeMethod时崩溃 我是不是弄错了什么 //main.cpp #include <QtCore> #include "entrypointclass.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << a.thread()-

我正在尝试使用invokeMethod调用另一个线程的方法,而不是Main。不幸的是,这会使应用程序在尝试执行invokeMethod时崩溃

我是不是弄错了什么

//main.cpp

#include <QtCore>
#include "entrypointclass.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << a.thread()->currentThreadId() << " - Application started.";

    EntryPointClass entryPoint;
    entryPoint.runInNewThread();
    return a.exec();
}
//入口点

#ifndef ENTRYPOINTCLASS_H
#define ENTRYPOINTCLASS_H

#include "worker.h"
#include <QtCore>

class EntryPointClass : public QObject
{
    Q_OBJECT
public:
    EntryPointClass();
    ~EntryPointClass();
    void runInNewThread();
public slots:
    void timeoutExpired();
private:
    Worker* m_Worker;
    QThread* m_Thread;
};

#endif // ENTRYPOINTCLASS_H
//Entrypoint.cpp

#include <QTCore>
#include "entrypointclass.h"
#include "Worker.h"

EntryPointClass::EntryPointClass()
{
    qDebug() << "EntryPointClass created";



}

EntryPointClass::~EntryPointClass()
{
    qDebug() << "EntryPointClass destroyed";
}

void EntryPointClass::runInNewThread()
{
    QThread* m_Thread = new QThread;
    Worker* m_Worker = new Worker();


    connect(m_Thread, SIGNAL(started()), m_Worker, SLOT(doSomething()));
    connect(m_Worker, SIGNAL(finished()), m_Thread, SLOT(quit()));
    connect(m_Thread, SIGNAL(finished()), m_Thread, SLOT(deleteLater()));
    connect(m_Thread, SIGNAL(finished()), m_Worker, SLOT(deleteLater()));

    QTimer* timer = new QTimer;
    timer->setSingleShot(true);

    //bool bOK = connect(timer, SIGNAL(timeout()), m_Worker, SLOT(closeWorker()), Qt::BlockingQueuedConnection);

    connect(timer, SIGNAL(timeout()), this, SLOT(timeoutExpired()));

    m_Worker->moveToThread(m_Thread);
    m_Thread->start();
    timer->start(5000);

}

void EntryPointClass::timeoutExpired()
{
    qDebug() << "timeout expired";
    if (m_Worker != NULL)
    {
        QMetaObject::invokeMethod(m_Worker, "closeWorker", Qt::QueuedConnection);
    }
}
//工人

#ifndef WORKER_H
#define WORKER_H

#include <QtCore>

class Worker : public QObject
{
    Q_OBJECT
public:
    Worker();
    ~Worker();

public slots:
    void doSomething();
    void closeWorker();

private:
    bool m_bAbort;
    QMutex m_mutex;


signals:
    void finished();
};

#endif // WORKER_H
//Worker.cpp

#include "worker.h"
#include <unistd.h>
#include "QTcore"

Worker::Worker()
    : m_mutex()
{
    qDebug() << this->thread()->currentThreadId() << "Worker created";
    m_bAbort = false;
    //qDebug() << QString("Thread %1 - Worker created").arg("");//this->thread()->currentThreadId());
}

Worker::~Worker()
{
    qDebug() << this->thread()->currentThreadId() << "Worker destroyed";

}

void Worker::doSomething()
{
    while(!m_bAbort)
    {
        sleep(2);
        qDebug() << this->thread()->currentThreadId() << "Do Something!";
    }

    emit finished();
}

void Worker::closeWorker()
{
    qDebug() << this->thread()->currentThreadId() << "closeWorker triggered!";
    QMutexLocker mutexLocker(&m_mutex);
    m_bAbort = true;
}

尝试发布自定义事件,而不是直接调用方法。这将要求您在处理自定义事件的目标上实现事件筛选器。只要目标线程中的事件循环处于活动状态,事件发布始终有效

再看看这个答案。而且
希望这有帮助。

QtQueuedConnection使方法在目标线程的事件循环中被调用。由于您停留在while循环中,所以线程永远不会到达事件循环中的close worker调用。您可以尝试调用processEvents或直接在源线程中调用closeWorker方法。为什么要使用invokeMethod,而不是将信号连接到插槽并仅发出该信号?为什么要使用更复杂的方法来执行基本相同的操作?