Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Problem in Multithreading Application
Forum Updated to NodeBB v4.3 + New Features

Problem in Multithreading Application

Scheduled Pinned Locked Moved General and Desktop
15 Posts 6 Posters 5.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    vidar
    wrote on last edited by
    #1

    Hi,

    I have two threads:

    • the main application containing the GUI
    • and a second one that I use to update the values of an array, whenever settings in the GUI change.

    To notify the worker thread, I emit a signal that is connected with a slot of the worker's thread:

    @connect(this, SIGNAL (updateArr(QPainterPath)),
    this->threadUpdater,SLOT (updateArr(QPainterPath)), Qt::QueuedConnection);@

    From the Qt Documentation I expected the slot to be executed in the worker's thread. I am using Mutexes to ensure, that accessing member values is safe:

    @void ThreadUpdater::updateArr(const QPainterPath &bezPath) {

    mutexUpdate->lock();
    doSomething(bezPath);
    mutexUpdate->unlock();
    }@

    However, when debugging the Application, I get the warning: "A mutex must be unlocked in the same thread that locked it.").

    It seems that, the slot is not called from within the worker's thread, as I expected... What am I doing wrong?

    The worker's thread does install an event loop:
    @void ThreadUpdater::run() {
    mutexUpdate = new QMutex();
    exec();
    delete mutexUpdate;
    }

    void ThreadUpdater::stopThread() {
    quit();
    }@

    1 Reply Last reply
    0
    • V Offline
      V Offline
      vsorokin
      wrote on last edited by
      #2

      Please, show, how you create working thread object (ThreadUpdater).

      --
      Vasiliy

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #3

        Seems like that thread is constructed wrong. Read "this article":http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects on the wiki please.

        1 Reply Last reply
        0
        • G Offline
          G Offline
          giesbert
          wrote on last edited by
          #4

          [quote author="vidar" date="1318347835"]Hi,
          To notify the worker thread, I emit a signal that is connected with a slot of the worker's thread:

          @connect(this, SIGNAL (updateArr(QPainterPath)),
          this->threadUpdater,SLOT (updateArr(QPainterPath)), Qt::QueuedConnection);@

          From the Qt Documentation I expected the slot to be executed in the worker's thread. I am using Mutexes to ensure, that accessing member values is safe:
          [/quote]

          This is only true, if you moved the thread object to be attached to the thread itself. Each QObject has a thread affinity to the thread that created it. The QThread object itself is a QObject that hosts a thread, but its affinity is towards its creator thread. Tho change that, use moveToThread.

          Nokia Certified Qt Specialist.
          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            I don't think that using moveToThread on the thread object itself is very good advice. Instead, it would be better to start using QThread like this:

            @
            MyWorkerObject* worker = new MyWorkerObject();
            QThread* workerThread = new QThread(this);
            worker->moveToThread(workerThread);
            connect(this, SIGNAL(someSignal()), worker, SLOT(someSlot()));
            workerThread->start();
            @

            That is: use a vanilla QThread (not a subclass), and use a QObject-derived worker object that you move to the worker thread object.

            1 Reply Last reply
            0
            • V Offline
              V Offline
              vidar
              wrote on last edited by
              #6

              Thank you! I think I still need to meditate about the "the QThread object does not live in the Thread itself" - thing. But from the wiki article I read that it is a good way to connect the signal & slot from within the run() method of the QThread... Or to use the code that Andre posted. I will check it out.
              Thanks a lot!

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                To help you in your meditation: you should understand that QThread is an object that manages a thread, but it is not the thread itself. A thread is not an object, it is a path of code execution that runs parallel to another code execution path.

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  giesbert
                  wrote on last edited by
                  #8

                  [quote author="vidar" date="1318367955"]But from the wiki article I read that it is a good way to connect the signal & slot from within the run() method of the QThread... [/quote]

                  That would be even better and could remove the moveToThread thing.

                  Create a subclass of QThread and add some slots

                  connect the outside class with the slost of your thread object

                  you QThread should emit a signal for each slot

                  inside run, create the worker qobjects and connect them to your threads signals.

                  This decouples the worker objects from the outer world, removes the moveToThread stuff and from outside, it looks (and it also does) that the thread handles the stuff.

                  This is just another idea how to solve that.

                  Nokia Certified Qt Specialist.
                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #9

                    In that case, I would remove the QThread itself from view. Don't subclass it, but instead just subclass a QObject that you give the nessecairy API, and let that class care about what way of making the operations async it wants to use. That could be QThread, it could be not. I would really advice against subclassing QThread and adding slots and/or signals to it.

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      goetz
                      wrote on last edited by
                      #10

                      Wasn't that subclassing QThread exactly that "'You're doing it wrong'":http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ thing?

                      http://www.catb.org/~esr/faqs/smart-questions.html

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        giesbert
                        wrote on last edited by
                        #11

                        If you move the thread object, YES. But that wasn't my suggestion. My idea was to use it as multiplexer so you can create the target QObjects inside run and connect the signals there.

                        Nokia Certified Qt Specialist.
                        Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          goetz
                          wrote on last edited by
                          #12

                          In that case, I would recommend creating a plainly QObject derived class that keeps a QThread as member variable (or pointer). This way the implementation details do not leak to the outside, as the users of the class should not be exposed with the QThread methods directly.

                          http://www.catb.org/~esr/faqs/smart-questions.html

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #13

                            That's what I suggested as well:
                            [quote author="Andre" date="1318490455"]In that case, I would remove the QThread itself from view. Don't subclass it, but instead just subclass a QObject that you give the nessecairy API, and let that class care about what way of making the operations async it wants to use.[/quote]

                            Do not subclass just because it is convenient. Subclass because your object is (a specialized version of) the class you are subclassing and you intend to use it that way. In this case, encapsulation seems a much better solution.

                            1 Reply Last reply
                            0
                            • V Offline
                              V Offline
                              vidar
                              wrote on last edited by
                              #14

                              Hi,

                              looking at the philosophy of object-oriented design, Andre's and Volker's solution seems to be more "correct".
                              However, I somehow prefer the dataflow-oriented solution that Gerolf mentioned (subclassing of QThread and using it as a "proxy"), for the following reason: the overall application is clearly partitioned into "domains" in which things are done in parallel. The borders of these domains are the instances of the QThread subclasses and thus can be identified easily.

                              1 Reply Last reply
                              0
                              • M Offline
                                M Offline
                                mamtamehra
                                Banned
                                wrote on last edited by
                                #15
                                This post is deleted!
                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved