简体   繁体   中英

main thread cannot get signal form worker thread

This is part of the main.

This code create a worker and a workerthread.

The worker is moved to the workerthread.

The worker is then waiting for the signal to ask it to work.

The worker emit a signal with result when job done.

The main supposed to catch that signal and initialize a variable in the main.

main()
{.........
// This is the variable to be changed
variableToGetFromWorker = 0;

qDebug() << "Main thread: " << QThread::currentThreadId();

QThread workerThread;
worker* stupidTom = new stupidTom(number);

worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, &workerThread, &QObject::deleteLater);
connect(&workerThread, SIGNAL(start()), stupidTom, SLOT(doJob()));
connect(stupidTom, SIGNAL(jobDone(int)), this, SLOT(jobDone(int)));

workerThread.start();
workerThread.wait();
...........}


// This is a slot at main. Suppose to catch the signal from the worker

void main::jobDone(int result)
{
    qDebug() << "Changing variable";
    variableToGetFromWorker = result;
}

This is the doJob slot of the worker.

void worker::doJob()
{
    qDebug() << "worker::doJob invoked.";
    qDebug() << "worker Thread:" << QThread::currentThreadId();

    // Doing Job here

    emit jobDone(result);
}

It is the qDebug result

Main thread:  0x7ffff7fc6780
worker::doJob invoked.
worker Thread: 0x7fffdab44700

In Debug mode, I find that the program is stop at workerThread.wait() and never go to main::jobDone(int result) . What is the reason?

Little editing on the main code:

QThread workerThread;
worker* stupidTom = new stupidTom(number);

worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, &workerThread, &QObject::deleteLater);
connect(&workerThread, SIGNAL(started()), stupidTom, SLOT(doJob()));
connect(stupidTom, SIGNAL(jobDone(int)), this, SLOT(jobDone(int)));
connect(stupidTom, SIGNAL(jobDone(int)), &workerThread, SLOT(quit()));

workerThread.start();
workerThread.wait();

As long as signals supposed to invoke slots. That won't be working on wait() on the main thread that supposed to run the slot or specifically jobDone signal.

Make sure to understand the difference between QThread::exec() and QThread::wait() in your application. Normally in the real app your thread would be looping (running) while the thread that launched it is still looping as well. The loop is implemented in protected QThread::exec() method. We usually don't need to call exec() explicitly but we need to allow the thread to run. You can do that by making main function to use QEventLoop for looping:

int main()
{
//...
    workerThread.start();
    QEventLoop eventLoop;
// here you will probably want to hook-up QEventLoop::quit() slot
// to eventually quit the process
    int returnCode = eventLoop.exec();
//...
    return returnCode;
}

And this is also wrong:

connect(&workerThread, SIGNAL(start()), stupidTom, SLOT(doJob()));

Instead you should create your own job object and do QObject::moveToThread for it. Here is a nice article about it. So it should rather look like:

connect(&workerThread, SIGNAL(started()), stupidTom, SLOT(doJob()));

I likely understand why you attempted to run the thread that way as above. It is similar to many C++ examples. You can also do that in Qt but you also need to realize how exactly you'll be waiting on completion of workerThread. And Qt most popular way to do the interaction between threads is with signals and slots. That is why we should use QEventLoop in main. But of course there is an alternative. For lower level plain C++ you can use mutex and condition variable to accomplish the same. Or that same wait() but then there is no signals involved.

Also watch the debug output, whether or not all the connect statements really connect proper signals to slots. In case if there is no connect it prints the warning.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM