Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Threads issues



  • Hi all

    I'm a newbie in the Qt. Lately I have discovered confused situation about the QThread usage.
    I read the:
    http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/

    the idea presented there I like. I tried to use it in my application. I got the issue which is not touched, at least I haven't seen any info about it:
    @
    class MyWorker : public QObject{
    Q_OBJECT
    public slots:
    void doWork(){
    //bla
    }
    };

    int main(){
        //..
        OtherObject a;
        MyWorker b;
        QThread t;
        b.moveToThread(&t);
        connect(&a,SIGNAL(workReady()),&b,SLOT(doWork()));
        t.start();
        //..
    }
    

    @

    Now this is just an example. In my app I create the:
    MyWorker b;
    QThread t;

    in the class.

    The problem is when the destructor is called when app exits. After:
    b.moveToThread(&t);

    the "b" object is in another thread. So I get the assert when the application is closed. This is due to the fact that destructor of MyWorker is called from another thread than object is.

    Have anyone has a nice solution for this??

    songoku

    EDIT1
    Maybe I'll tell you how I solve the problem:

    @class MainWorkerThread: public Thread
    {
    MainWorkerThread():QThread()
    {
    mMyWorker = new MyWorker();
    mMyWorker->moveToThread(this);
    }
    ~MainWorkerThread()
    {
    wait();
    }

    MyWorker* getHwBtnControler()
    {
        return mMyWorker;
    }
    

    protected:
    void run()
    {
    exec();

        delete mMyWorker;
        mMyWorker = NULL;
    }
    

    private:
    MyWorker *mMyWorker;
    }@

    But for some reason I'm not very happy with this :)



  • Have you read "pepes wiki article about threads":http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects ?

    Threads / events and object destruction must be handled correctly.

    You should create the MyWorker object inside the run method, thats better...
    Otherwise you have a memory leak, if you ctreate the thread object but do not start it or starting fails.



  • You either need to destroy object in the same thread or use QObject::moveToThread().



  • Gerolf thanks for the article :) I missed it

    It can be done like this:

    in the class which constructed the MainWorker and MainWorkerThread (which is now a simple QThread
    obejct not a subclass) I move MainWorker to the new thread. (with moveToThread())

    in the descturor of the class (which owns the MainWorker and the MainWorkerThread) I call MainWroker->deleteLater() instead of actually deleting the MainWorker object.

    This solution works only in MainWorker is created on the heap, though. But in my case this is not an issue.

    Creating and deleting in run() method of subclass of the QThread shall work as well. But for me it just does not look good :)

    What do you think about this solution?



  • It will works if you wait for destruction of the thread in your destructor. But you must initiate an eventLoop end on the thread.
    so call deleteLater and then thread.quit().


Log in to reply