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. QTextDocument and Multithreading
QtWS25 Last Chance

QTextDocument and Multithreading

Scheduled Pinned Locked Moved Solved General and Desktop
qtextdocumentmultithreads
23 Posts 3 Posters 11.9k Views
  • 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.
  • T Tyras
    19 Feb 2016, 23:11

    @SGaist

    you should rather not give the parent parameter and then move your cloned QTextDocument to your current thread with moveToThread.

    Should I just ignore the warning, and just move to the current thread, then? It's the clone method that gives the warning (confirmed it in debug).

    K Offline
    K Offline
    kshegunov
    Moderators
    wrote on 19 Feb 2016, 23:15 last edited by
    #14

    @Tyras
    No.
    If logFrags is QVector<QTextDocument> then this:

    logFrags->first()->clone(this)
    

    Will parent it to your parser object, which lives in your parser thread. Assuming that vector comes from another thread, then it causes issues.
    Something like this, should be working okay:

    QTextDocument * fragDoc = logFrags->first()->clone();
    fragDoc->moveToThread(QThread::currentThread());
    

    Kind regards.

    Read and abide by the Qt Code of Conduct

    T 1 Reply Last reply 19 Feb 2016, 23:19
    0
    • K kshegunov
      19 Feb 2016, 23:15

      @Tyras
      No.
      If logFrags is QVector<QTextDocument> then this:

      logFrags->first()->clone(this)
      

      Will parent it to your parser object, which lives in your parser thread. Assuming that vector comes from another thread, then it causes issues.
      Something like this, should be working okay:

      QTextDocument * fragDoc = logFrags->first()->clone();
      fragDoc->moveToThread(QThread::currentThread());
      

      Kind regards.

      T Offline
      T Offline
      Tyras
      wrote on 19 Feb 2016, 23:19 last edited by
      #15

      @kshegunov
      Just tried your code.

      QTextDocument * fragDoc = logFrags->first()->clone();
      

      outputs:

      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QTextDocument(0x4b9ae26640), parent's thread is QThread(0x4b9acaa630), current thread is QThread(0x4b97a007c0)
      

      When a coder says that it's impossible to do something, he's actually feeling too lazy to do it.

      K 1 Reply Last reply 19 Feb 2016, 23:21
      0
      • T Tyras
        19 Feb 2016, 23:19

        @kshegunov
        Just tried your code.

        QTextDocument * fragDoc = logFrags->first()->clone();
        

        outputs:

        QObject: Cannot create children for a parent that is in a different thread.
        (Parent is QTextDocument(0x4b9ae26640), parent's thread is QThread(0x4b9acaa630), current thread is QThread(0x4b97a007c0)
        
        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 19 Feb 2016, 23:21 last edited by
        #16

        Yes, I'm missing on something it seems. Why would you want to clone the objects anyway, can you just push them into the current thread?

        QTextDocument * fragDoc = logFrags->first();
        fragDoc->moveToThread(QThread::currentThread());
        

        Read and abide by the Qt Code of Conduct

        T 1 Reply Last reply 19 Feb 2016, 23:38
        0
        • K kshegunov
          19 Feb 2016, 23:21

          Yes, I'm missing on something it seems. Why would you want to clone the objects anyway, can you just push them into the current thread?

          QTextDocument * fragDoc = logFrags->first();
          fragDoc->moveToThread(QThread::currentThread());
          
          T Offline
          T Offline
          Tyras
          wrote on 19 Feb 2016, 23:38 last edited by
          #17

          @kshegunov

          Why would you want to clone the objects anyway, can you just push them into the current thread?

          Because I need to push it in the thread that created it... but, well, since the target thread is a singleton, it won't be so ugly.

          When a coder says that it's impossible to do something, he's actually feeling too lazy to do it.

          K 1 Reply Last reply 19 Feb 2016, 23:40
          0
          • T Tyras
            19 Feb 2016, 23:38

            @kshegunov

            Why would you want to clone the objects anyway, can you just push them into the current thread?

            Because I need to push it in the thread that created it... but, well, since the target thread is a singleton, it won't be so ugly.

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 19 Feb 2016, 23:40 last edited by
            #18

            @Tyras

            since the target thread is a singleton

            I don't understand this. Do you mean to tell that the QThread object is a singleton?

            Read and abide by the Qt Code of Conduct

            T 1 Reply Last reply 19 Feb 2016, 23:47
            0
            • K kshegunov
              19 Feb 2016, 23:40

              @Tyras

              since the target thread is a singleton

              I don't understand this. Do you mean to tell that the QThread object is a singleton?

              T Offline
              T Offline
              Tyras
              wrote on 19 Feb 2016, 23:47 last edited by
              #19

              @kshegunov
              Sorry, I meant that the instance of the class that receives the QTextDocument is a singleton

              When a coder says that it's impossible to do something, he's actually feeling too lazy to do it.

              K 1 Reply Last reply 19 Feb 2016, 23:49
              0
              • T Tyras
                19 Feb 2016, 23:47

                @kshegunov
                Sorry, I meant that the instance of the class that receives the QTextDocument is a singleton

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 19 Feb 2016, 23:49 last edited by kshegunov
                #20

                @Tyras
                You shouldn't have singletons in the first place, much less QObject derived singletons.
                That being said, you'll have to tell where are the instances in the logFrags vector (if it's a vector) created and where the JsonParser object is residing, and by where I mean in what thread.

                Additionally my previous comment:

                Yes, I'm missing on something it seems. Why would you want to clone the objects anyway, can you just push them into the current thread?

                Is absolutely wrong, since I was suggesting you try to "pull" an object from another thread, which is not possible.

                Kind regards.

                Read and abide by the Qt Code of Conduct

                T 1 Reply Last reply 20 Feb 2016, 00:08
                0
                • K kshegunov
                  19 Feb 2016, 23:49

                  @Tyras
                  You shouldn't have singletons in the first place, much less QObject derived singletons.
                  That being said, you'll have to tell where are the instances in the logFrags vector (if it's a vector) created and where the JsonParser object is residing, and by where I mean in what thread.

                  Additionally my previous comment:

                  Yes, I'm missing on something it seems. Why would you want to clone the objects anyway, can you just push them into the current thread?

                  Is absolutely wrong, since I was suggesting you try to "pull" an object from another thread, which is not possible.

                  Kind regards.

                  T Offline
                  T Offline
                  Tyras
                  wrote on 20 Feb 2016, 00:08 last edited by
                  #21

                  @kshegunov

                  You shouldn't have singletons in the first place, much less QObject derived singletons.

                  I don't really understand why, since the class is a controller, I should never have more than one instance of it in my application, And I should be able to access this single instance through all the code... besides, singletons are a design pattern... And it is QObject derivated because it must live in it's own thread.

                  But, that aside, I'll just have the worker threads push the QTextDocument objects to JsonParser threads after they finish them.

                  Thanks for the help!

                  When a coder says that it's impossible to do something, he's actually feeling too lazy to do it.

                  K 1 Reply Last reply 20 Feb 2016, 01:46
                  0
                  • T Tyras
                    20 Feb 2016, 00:08

                    @kshegunov

                    You shouldn't have singletons in the first place, much less QObject derived singletons.

                    I don't really understand why, since the class is a controller, I should never have more than one instance of it in my application, And I should be able to access this single instance through all the code... besides, singletons are a design pattern... And it is QObject derivated because it must live in it's own thread.

                    But, that aside, I'll just have the worker threads push the QTextDocument objects to JsonParser threads after they finish them.

                    Thanks for the help!

                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 20 Feb 2016, 01:46 last edited by kshegunov
                    #22

                    @Tyras

                    I don't really understand why, since the class is a controller, I should never have more than one instance of it in my application, And I should be able to access this single instance through all the code... besides, singletons are a design pattern... And it is QObject derivated because it must live in it's own thread.

                    You shouldn't have singletons because:

                    1. A singleton is not a real object, it's a facade for a global variable
                    2. A singleton created on the stack is initialized before main, so anything that actually depends on things done in main() as QObject does, may or may not work.
                    3. A singleton that's constructed on the heap often is simply left undeleted - a memory leak. C++ is not JAVA, it's the programmers job to clean the memory up.
                    4. A singleton that's created on first use in the heap requires special measures to be taken, so the construction is thread safe.
                    5. A singleton created on the stack can't guarantee order of initialization (whence point 2 derives). If you have more than one the loader will initialize them depending on its mood!
                    6. A singleton that's created on the heap can't guarantee order of initialization ever!
                    7. A singleton is a global shared public resource in your application that promotes coupling, it actually couples every one of the classes that decide to use it.
                    8. A singleton is not thread-safe by design, and can't be reentrant as there is only one.

                    Why your worker object should not be a singleton:

                    1. Because you can have many worker objects in different threads.
                    2. Because if you want only one, you create only one! (And I just can't stress this enough)
                    3. Because the signal/slot mechanism is supposed to decouple your components, not the other way around.
                    4. Because object hierarchies work terribly with singletons, who's the root object is simply undefined.
                    5. The fact that something is called a "design pattern" in some book, doesn't mean you should use it.
                    6. Because something is possible, doesn't mean you should do it.

                    Have you seen singletons actually implemented in Qt? Yes, there are static functions, yes there are static variables (if you skim through the code) there's a lot of them actually. But have you seen a real life singleton in this enormously big library? I have not!

                    Simply apply some common sense! Create your nice worker object, connect its signals and slots, connect the cleanup routines and just rock its bloody world!

                    QObject::deleteLater is actually a slot and this is not at all a coincidence, neither is the QApplication::aboutToQuit signal a fling, nor is the QObject::destroyed(QObject *) signal an error.
                    My advice is: forget the "singleton design pattern" and enter the great world of OOP, yes a singleton breaks almost every rule in OOP.

                    Man, sometimes I just want to cry ... then I get angry, and then I surrender. I must be dying a little with each of these posts and I firmly believe I've given at least several of these impassioned preaches ...

                    Read and abide by the Qt Code of Conduct

                    T 1 Reply Last reply 20 Feb 2016, 02:26
                    1
                    • K kshegunov
                      20 Feb 2016, 01:46

                      @Tyras

                      I don't really understand why, since the class is a controller, I should never have more than one instance of it in my application, And I should be able to access this single instance through all the code... besides, singletons are a design pattern... And it is QObject derivated because it must live in it's own thread.

                      You shouldn't have singletons because:

                      1. A singleton is not a real object, it's a facade for a global variable
                      2. A singleton created on the stack is initialized before main, so anything that actually depends on things done in main() as QObject does, may or may not work.
                      3. A singleton that's constructed on the heap often is simply left undeleted - a memory leak. C++ is not JAVA, it's the programmers job to clean the memory up.
                      4. A singleton that's created on first use in the heap requires special measures to be taken, so the construction is thread safe.
                      5. A singleton created on the stack can't guarantee order of initialization (whence point 2 derives). If you have more than one the loader will initialize them depending on its mood!
                      6. A singleton that's created on the heap can't guarantee order of initialization ever!
                      7. A singleton is a global shared public resource in your application that promotes coupling, it actually couples every one of the classes that decide to use it.
                      8. A singleton is not thread-safe by design, and can't be reentrant as there is only one.

                      Why your worker object should not be a singleton:

                      1. Because you can have many worker objects in different threads.
                      2. Because if you want only one, you create only one! (And I just can't stress this enough)
                      3. Because the signal/slot mechanism is supposed to decouple your components, not the other way around.
                      4. Because object hierarchies work terribly with singletons, who's the root object is simply undefined.
                      5. The fact that something is called a "design pattern" in some book, doesn't mean you should use it.
                      6. Because something is possible, doesn't mean you should do it.

                      Have you seen singletons actually implemented in Qt? Yes, there are static functions, yes there are static variables (if you skim through the code) there's a lot of them actually. But have you seen a real life singleton in this enormously big library? I have not!

                      Simply apply some common sense! Create your nice worker object, connect its signals and slots, connect the cleanup routines and just rock its bloody world!

                      QObject::deleteLater is actually a slot and this is not at all a coincidence, neither is the QApplication::aboutToQuit signal a fling, nor is the QObject::destroyed(QObject *) signal an error.
                      My advice is: forget the "singleton design pattern" and enter the great world of OOP, yes a singleton breaks almost every rule in OOP.

                      Man, sometimes I just want to cry ... then I get angry, and then I surrender. I must be dying a little with each of these posts and I firmly believe I've given at least several of these impassioned preaches ...

                      T Offline
                      T Offline
                      Tyras
                      wrote on 20 Feb 2016, 02:26 last edited by
                      #23

                      @kshegunov
                      I understand, and respect your opinion on the matter but... I doesn't agree with most of them. Not wanting to make a big discussion of it, (mainly 'cause it's really out of the scope of the post) but...

                      let's see:

                      A singleton is not a real object, it's a facade for a global variable

                      Well, yeah. I would say it's a (much) more elegant way to create a "global variable", since it ensures that only one will be created.

                      A singleton created on the stack is initialized before main, so anything that actually depends on things done in main() as QObject does, may or may not work.

                      Well, the way I learned to implement singleton on C++ uses heap.

                      A singleton that's constructed on the heap often is simply left undeleted - a memory leak. C++ is not JAVA, it's the programmers job to clean the memory up.

                      Well, I'm not seeing a problem here. I dont mind putting a few deletes at the end of my main, or even connecting some signals.

                      A singleton that's created on first use in the heap requires special measures to be taken, so the construction is thread safe.

                      Again, not seeing a problem here, just a need to take some caution when coding.

                      A singleton created on the stack can't guarantee order of initialization (whence point 2 derives). If you have more than one the loader will initialize them depending on its mood!

                      Again, I don't create them on stack.

                      A singleton that's created on the heap can't guarantee order of initialization ever!

                      Not really sure what you mean here.

                      A singleton is a global shared public resource in your application that promotes coupling, it actually couples every one of the classes that decide to use it.

                      Some times you need that coupling. You need to center the processing in one point in the code. That's what controllers are all about.

                      A singleton is not thread-safe by design, and can't be reentrant as there is only one.

                      Not really. For data classes, you're right. But for controllers, they can be thread safe as long as their attributes are read-only

                      Why your worker object should not be a singleton

                      My worker object is not a singleton. My controller object (the one that creates the worker objects) is.

                      The fact that something is called a "design pattern" in some book, doesn't mean you should use it.

                      But means that it have its uses.

                      When a coder says that it's impossible to do something, he's actually feeling too lazy to do it.

                      1 Reply Last reply
                      0

                      23/23

                      20 Feb 2016, 02:26

                      • Login

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