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. ASSERT: "isDetached()" with multithreaded QVectors
QtWS25 Last Chance

ASSERT: "isDetached()" with multithreaded QVectors

Scheduled Pinned Locked Moved Unsolved General and Desktop
18 Posts 7 Posters 5.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.
  • J Offline
    J Offline
    jars121
    wrote on 26 Apr 2018, 00:05 last edited by
    #1

    I have a number of QVectors in my application, each of which is modified (data inserted into a particular field of the QVector) by functions across a number of threads.

    In debug() mode the application will run for a period of time (could be 5 seconds, could be a minute) before being killed with the following assertion:

    ASSERT: "isDetached()" in file /opt/pathToinclude/include/QtCore/qvector.h, line 386
    Aborted
    

    The section of code in qvector.h resulting in the assertion on line 386 is as follows:

    template <typename T>
    void QVector<T>::detach()
    {
        if (!isDetached()) {
    #if !defined(QT_NO_UNSHARABLE_CONTAINERS)
            if (!d->alloc)
                d = Data::unsharableEmpty();
            else
    #endif
                reallocData(d->size, int(d->alloc));
            }
            Q_ASSERT(isDetached());
        }
    

    What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

    If not, what is going on here and what's the advise approaching for fixing it?

    S 1 Reply Last reply 26 Apr 2018, 03:56
    1
    • J jars121
      26 Apr 2018, 00:05

      I have a number of QVectors in my application, each of which is modified (data inserted into a particular field of the QVector) by functions across a number of threads.

      In debug() mode the application will run for a period of time (could be 5 seconds, could be a minute) before being killed with the following assertion:

      ASSERT: "isDetached()" in file /opt/pathToinclude/include/QtCore/qvector.h, line 386
      Aborted
      

      The section of code in qvector.h resulting in the assertion on line 386 is as follows:

      template <typename T>
      void QVector<T>::detach()
      {
          if (!isDetached()) {
      #if !defined(QT_NO_UNSHARABLE_CONTAINERS)
              if (!d->alloc)
                  d = Data::unsharableEmpty();
              else
      #endif
                  reallocData(d->size, int(d->alloc));
              }
              Q_ASSERT(isDetached());
          }
      

      What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

      If not, what is going on here and what's the advise approaching for fixing it?

      S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 26 Apr 2018, 03:56 last edited by
      #2

      @jars121 said in ASSERT: "isDetached()" with multithreaded QVectors:

      What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

      Use a QMutex to guard the write.

      Detaching is done when a copy of QVector is being done. That happens each time you pass a vector by value, or when you assign one vector to some other variable. Why it fails, though, I have no idea. Perhaps try asking on Qt interest mailing list where Qt devs reside - they'll surely know more details.

      (Z(:^

      A J 2 Replies Last reply 26 Apr 2018, 04:00
      3
      • S sierdzio
        26 Apr 2018, 03:56

        @jars121 said in ASSERT: "isDetached()" with multithreaded QVectors:

        What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

        Use a QMutex to guard the write.

        Detaching is done when a copy of QVector is being done. That happens each time you pass a vector by value, or when you assign one vector to some other variable. Why it fails, though, I have no idea. Perhaps try asking on Qt interest mailing list where Qt devs reside - they'll surely know more details.

        A Offline
        A Offline
        aha_1980
        Lifetime Qt Champion
        wrote on 26 Apr 2018, 04:00 last edited by
        #3

        @sierdzio said in ASSERT: "isDetached()" with multithreaded QVectors:

        @jars121 said in ASSERT: "isDetached()" with multithreaded QVectors:

        What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

        Use a QMutex to guard the write.

        Detaching is done when a copy of QVector is being done. That happens each time you pass a vector by value, or when you assign one vector to some other variable. Why it fails, though, I have no idea.

        if you modify the object from two threads, anything can happen.

        i assume the vector is already in the state of detaching and then requested to detach again from the second thread.

        Qt has to stay free or it will die.

        1 Reply Last reply
        3
        • S sierdzio
          26 Apr 2018, 03:56

          @jars121 said in ASSERT: "isDetached()" with multithreaded QVectors:

          What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

          Use a QMutex to guard the write.

          Detaching is done when a copy of QVector is being done. That happens each time you pass a vector by value, or when you assign one vector to some other variable. Why it fails, though, I have no idea. Perhaps try asking on Qt interest mailing list where Qt devs reside - they'll surely know more details.

          J Offline
          J Offline
          jars121
          wrote on 26 Apr 2018, 04:22 last edited by
          #4

          @sierdzio said in ASSERT: "isDetached()" with multithreaded QVectors:

          @jars121 said in ASSERT: "isDetached()" with multithreaded QVectors:

          What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

          Use a QMutex to guard the write.

          Detaching is done when a copy of QVector is being done. That happens each time you pass a vector by value, or when you assign one vector to some other variable. Why it fails, though, I have no idea. Perhaps try asking on Qt interest mailing list where Qt devs reside - they'll surely know more details.

          Thank you @sierdzio. I'll post on the mailing list as recommended, as I've been making changes to my code all day and don't appear to be making any progress.

          @aha_1980 said in ASSERT: "isDetached()" with multithreaded QVectors:

          @sierdzio said in ASSERT: "isDetached()" with multithreaded QVectors:

          @jars121 said in ASSERT: "isDetached()" with multithreaded QVectors:

          What exactly is happening here? Is the detachment occurring because simultaneous edits of a QVector from several threads are being attempted? If so, what is the recommended means for preventing this?

          Use a QMutex to guard the write.

          Detaching is done when a copy of QVector is being done. That happens each time you pass a vector by value, or when you assign one vector to some other variable. Why it fails, though, I have no idea.

          if you modify the object from two threads, anything can happen.

          i assume the vector is already in the state of detaching and then requested to detach again from the second thread.

          Thank you @aha_1980. Would sierdzo's recommendation of using a QMutex aid in preventing this in any way? If not, can you recommend a strategy? Would replace QVectors with dedicated variables solve this issue?

          I.e. I'm using a QVector to save the output values for 5 calculations. I.e. outputVector=[v1, v2, v3, v4, v5]. v1 through v5 can be updated from different threads, which is likely the cause of the issue. If, instead of using outputVector, I had outputValue1, outputValue2, ..., outputValue5, this issue should be fixed?

          If I did use this approach, is there a way to loop through the variables in a for loop like I could with a QVector?

          e.g.

          for (int i(i); i < 6; i++) {
              outputValue[i] = 5;
          }
          

          The above is possible (although not written in that form obviously) in Python, but I haven't come across it in c++ as of yet. I'd happily swap my current QVectors with dedicated variables if the ability to address the variable within a for loop were possible.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            aha_1980
            Lifetime Qt Champion
            wrote on 26 Apr 2018, 06:35 last edited by
            #5

            @jars121 said in ASSERT: "isDetached()" with multithreaded QVectors:

            Would sierdzo's recommendation of using a QMutex aid in preventing this in any way? If not, can you recommend a strategy? Would replace QVectors with dedicated variables solve this issue?

            Using mutexes or semaphores is the usual way of protecting variables against concurrent access.

            The only variables that don't need protection are variables that can be changed in one (atomic) CPU cycle. This depends a bit on the machine and needs a deep understanding whats going on from programmes side.

            Also note, that simple operations in C decode to multiple machine commands: int a = 3; usually means: load the constant 3 into a register and then store it into the memory occupied by a.

            Even worse ist the following: a += 4 because that means: load the value from the memory a into a register, add the constant 4 and store the value back. This is not atomic. If you do this from two threads, a can contain anything afterwards.

            Regards

            Qt has to stay free or it will die.

            1 Reply Last reply
            3
            • J Offline
              J Offline
              jars121
              wrote on 26 Apr 2018, 22:43 last edited by
              #6

              A bit of a development; I added a qDebug() << "Main Thread: "" << QThread::currentThread(); at the start of main.cpp, and it appears that my main class is being run twice. This is definitely not per the design, and is likely causing all sorts of issues. I'm tracing through the code at the moment and will hopefully fix this issue when I can resolve the doubling up.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jars121
                wrote on 27 Apr 2018, 04:23 last edited by
                #7

                I appear to have fixed the issue with the following changes:

                1. Removed the duplication error mentioned above; I was accidentally instantiating my main class twice.
                2. I created a new class to manage the shared QVectors separate to my main class.
                3. I've incorporated QMutexLockers into each function which modifies the shared QVectors.

                The application has been running for around 20 minutes now without issue, so I'm hopeful that the detaching error is resolved.

                A 1 Reply Last reply 27 Apr 2018, 04:52
                2
                • J jars121
                  27 Apr 2018, 04:23

                  I appear to have fixed the issue with the following changes:

                  1. Removed the duplication error mentioned above; I was accidentally instantiating my main class twice.
                  2. I created a new class to manage the shared QVectors separate to my main class.
                  3. I've incorporated QMutexLockers into each function which modifies the shared QVectors.

                  The application has been running for around 20 minutes now without issue, so I'm hopeful that the detaching error is resolved.

                  A Offline
                  A Offline
                  aha_1980
                  Lifetime Qt Champion
                  wrote on 27 Apr 2018, 04:52 last edited by
                  #8

                  @jars121 thanks for your feedback.

                  sounds like a clean solution.

                  so please mark this topic as SOLVED now. Thanks

                  Qt has to stay free or it will die.

                  1 Reply Last reply
                  1
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 27 Apr 2018, 06:26 last edited by
                    #9

                    Hi,

                    Just an additional tool worth mentioning: QReadWriteLock. If you are reading from several threads then you can easily access your data and as soon as there's a write going it will lock the access. It might be faster than QMutex.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    2
                    • J Offline
                      J Offline
                      jars121
                      wrote on 27 Apr 2018, 11:33 last edited by
                      #10

                      Thanks @SGaist I had seen mention of QReadWriteLock in my travels, but hadn't yet put any serious thought into it. I'll be sure to read further and do some testing between it and QMutex.

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        jars121
                        wrote on 11 May 2018, 02:55 last edited by
                        #11

                        I've marked this as 'Unsolved', as I'm afraid I'm still battling this "isDetached()" assertion.

                        Following SGaist's recommendation above, I've actually gone through my entire application and removed all QMutex, and replaced them with QReadWriteLocks. In short, wherever I'm reading from or writing to a shared (between QThreads) QVector, QList, etc., there's a QReadLocker or QWriteLocker (respectively) present. However, the issue remains that after a seemingly random period of time, the application will crash (in Debug mode) with the "isDetached()" assertion.

                        I've done some further research on this issue, and found a similar reference to this assertion here. The findings/recommendations in that thread boil down to this:

                        • Using the [] operator to retrieve an item at the specified index in a QVector can create a deep copy situation, which is from where a detached() scenario could arise. This is specified in the QVector Class documentation.
                        • Using at() to retrieve an item at the specified index in a QVector is the preferred approach if not modifying the QVector.

                        As it turns out, I've never used at() before, and have been completely unaware of this distinction. I'm going through my code now, with the intention of replacing all read-only QVector operator references with at().

                        The use of at() won't assert "isDetached()", so hopefully this solves this particular issue once and for all. I'll update the thread with my findings.

                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          jars121
                          wrote on 11 May 2018, 05:36 last edited by
                          #12

                          Well the above certainly doesn't appear to have made any difference whatsoever. I've replaced every single instance of read-only [] QVector and QList operator with .at(), but the "isDetached()" assertion is still present.

                          One question as I continue to review the c++ side of my application; when reading from an exposed c++ QVector in QML, is vector[i] the only/recommended way of retrieving a value from index i? The reason I ask is I might accidentally be inducing a deep copy on the QML side without knowing it. The documentation suggests that the [] operators are the correct approach, but I wanted to confirm before dismissing QML as the potential cause of this extremely frustrating issue.

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Online
                            Christian EhrlicherC Online
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on 11 May 2018, 05:40 last edited by
                            #13

                            This will definitely not fix your problems but only hide it. When using objects in multiple threads you have to sync the access with a mutex or similar as explained by SGaist and others. If you don't do it you will get into trouble sooner or later.

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            1 Reply Last reply
                            2
                            • J Offline
                              J Offline
                              jars121
                              wrote on 11 May 2018, 06:00 last edited by
                              #14

                              I figured that's what I was doing by using QReadWriteLock and corresponding QReadLockers and QWriteLockers when interacting with the shared QVectors, QLists, etc?

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                jars121
                                wrote on 11 May 2018, 06:59 last edited by
                                #15

                                Ok so I've removed all the QReadWriteLock, QReadLocker and QWriteLocker instances, and have gone back to QMutex with QMutexLockers. I've been somewhat more diligent this time around, and in combination with the change from [] operators to .at() the application seems to be running smoothly.

                                I've got further testing to do before I'm completely comfortable, so I'll leave the thread open for the time being.

                                Y 1 Reply Last reply 20 Jul 2018, 21:15
                                0
                                • J jars121
                                  11 May 2018, 06:59

                                  Ok so I've removed all the QReadWriteLock, QReadLocker and QWriteLocker instances, and have gone back to QMutex with QMutexLockers. I've been somewhat more diligent this time around, and in combination with the change from [] operators to .at() the application seems to be running smoothly.

                                  I've got further testing to do before I'm completely comfortable, so I'll leave the thread open for the time being.

                                  Y Offline
                                  Y Offline
                                  Yippiyak
                                  wrote on 20 Jul 2018, 21:15 last edited by
                                  #16

                                  @jars121

                                  did you ever solve this issue? I have the same problem

                                  1 Reply Last reply
                                  1
                                  • Z Offline
                                    Z Offline
                                    Zhengyang
                                    wrote on 2 Aug 2021, 16:13 last edited by
                                    #17

                                    Hi, @jars121
                                    Have you found a solution? I have the same problem. And I can not solve it by adding a QMutex.

                                    SGaistS 1 Reply Last reply 2 Aug 2021, 17:53
                                    0
                                    • Z Zhengyang
                                      2 Aug 2021, 16:13

                                      Hi, @jars121
                                      Have you found a solution? I have the same problem. And I can not solve it by adding a QMutex.

                                      SGaistS Offline
                                      SGaistS Offline
                                      SGaist
                                      Lifetime Qt Champion
                                      wrote on 2 Aug 2021, 17:53 last edited by
                                      #18

                                      @Zhengyang hi and welcome to devnet, it's described in the last post of @jars121.

                                      If QMutex does not solve your issue, you are likely misusing it.

                                      Interested in AI ? www.idiap.ch
                                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                      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