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. Exception of multi thread reading QSqlTableModel
Forum Updated to NodeBB v4.3 + New Features

Exception of multi thread reading QSqlTableModel

Scheduled Pinned Locked Moved Solved General and Desktop
39 Posts 5 Posters 4.6k 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.
  • KroMignonK KroMignon

    @tovax said in Exception of multi thread reading QSqlTableModel:

    If there are more threads that modify the database, then it is necessary to establish signal slot connections from these threads to all other threads.

    As @Christian-Ehrlicher already written, QSqlDatabase is not thread-safe, so you have 2 options:

    • do all DB stuff in one thread, by using signals/slots it is quit easy.
    • use as many QSqlDatabase connections as you have threads ==> take a look here for example: https://forum.qt.io/topic/103626/problem-with-sqlite-database-and-threads-database-is-locked/14
    tovaxT Offline
    tovaxT Offline
    tovax
    wrote on last edited by
    #20

    @KroMignon said in Exception of multi thread reading QSqlTableModel:

    do all DB stuff in one thread, by using signals/slots it is quit easy.

    It's easy to write data by using signals/slots, but is it necessary to copy a memory copy for reading data? Because DB data cannot be read directly from other threads...

    JonBJ 1 Reply Last reply
    1
    • tovaxT tovax

      @KroMignon said in Exception of multi thread reading QSqlTableModel:

      do all DB stuff in one thread, by using signals/slots it is quit easy.

      It's easy to write data by using signals/slots, but is it necessary to copy a memory copy for reading data? Because DB data cannot be read directly from other threads...

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #21

      @tovax
      Yes, this is the issue. As you say, emitting a signal to ask the main thread to do a write (setData()) for your thread is not so difficult. Your problem comes on trying to synchronise read access (data()).

      It is easier to maintain per-thread connections for that purpose. But that comes with other overheads, as discussed. Depends on how much of what you need to do when.

      1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #22

        Again: why do you think you need threads for simple reading data from the database? What heaviy computation do you do with those values?

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

        tovaxT 1 Reply Last reply
        1
        • Christian EhrlicherC Christian Ehrlicher

          Again: why do you think you need threads for simple reading data from the database? What heaviy computation do you do with those values?

          tovaxT Offline
          tovaxT Offline
          tovax
          wrote on last edited by
          #23

          @Christian-Ehrlicher
          The main purpose of thread is to process time-consuming algorithms and real-time control. Reading data from the database is only to obtain the global parameters needed in the algorithm and control process.

          JonBJ KroMignonK 2 Replies Last reply
          0
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by Christian Ehrlicher
            #24

            Then read your data in one thread, start/inform the workers that there is data and let them do the work. When you a mutex to protect read/write access to your data you don't even need to copy it. But that's plain threading stuff which you should read about before trying to actually writing something. Threading is not easy and should be avoided when not really needed for basic programmers.

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

            tovaxT 1 Reply Last reply
            1
            • tovaxT tovax

              @Christian-Ehrlicher
              The main purpose of thread is to process time-consuming algorithms and real-time control. Reading data from the database is only to obtain the global parameters needed in the algorithm and control process.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #25

              @tovax
              I was going to say as @Christian-Ehrlicher has just said. Can you not take the reading from the database outside the threads and then access some shared data only for the computations.

              @Christian-Ehrlicher
              Isn't the following a problem: is it not the case that for a reader accessing data() that calls rowCount() and that can cause physical call to database for fetchMore()?? Or does data()/rowCount() never do that, I can't recall?

              1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                Then read your data in one thread, start/inform the workers that there is data and let them do the work. When you a mutex to protect read/write access to your data you don't even need to copy it. But that's plain threading stuff which you should read about before trying to actually writing something. Threading is not easy and should be avoided when not really needed for basic programmers.

                tovaxT Offline
                tovaxT Offline
                tovax
                wrote on last edited by
                #26

                @Christian-Ehrlicher

                Some results of time-consuming algorithm and motion control need to be written to database, such as time, current position and so on. In other words, there will be frequent data interaction between some child threads and the database.

                1 Reply Last reply
                0
                • tovaxT tovax

                  @Christian-Ehrlicher
                  The main purpose of thread is to process time-consuming algorithms and real-time control. Reading data from the database is only to obtain the global parameters needed in the algorithm and control process.

                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by
                  #27

                  @tovax said in Exception of multi thread reading QSqlTableModel:

                  The main purpose of thread is to process time-consuming algorithms and real-time control. Reading data from the database is only to obtain the global parameters needed in the algorithm and control process.

                  I think you are "over-engineering" your programm.
                  For me, the steps your need are:

                  • getting computation parameters from db
                  • starting multiple computation operations

                  So I would do it like @Christian-Ehrlicher said:

                  • in main thread preparing data for computation ==> reading required data from DB
                  • start thread for computation ==> I would do it with QtConcurrent::run() and dedicated QThreadPool to avoid thread creation/destruction and to be able to wait for computation end with QFutureWatcher.

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  tovaxT 1 Reply Last reply
                  0
                  • KroMignonK KroMignon

                    @tovax said in Exception of multi thread reading QSqlTableModel:

                    The main purpose of thread is to process time-consuming algorithms and real-time control. Reading data from the database is only to obtain the global parameters needed in the algorithm and control process.

                    I think you are "over-engineering" your programm.
                    For me, the steps your need are:

                    • getting computation parameters from db
                    • starting multiple computation operations

                    So I would do it like @Christian-Ehrlicher said:

                    • in main thread preparing data for computation ==> reading required data from DB
                    • start thread for computation ==> I would do it with QtConcurrent::run() and dedicated QThreadPool to avoid thread creation/destruction and to be able to wait for computation end with QFutureWatcher.
                    tovaxT Offline
                    tovaxT Offline
                    tovax
                    wrote on last edited by
                    #28

                    f6eac6e3-dc96-4302-b4a7-013d02ffa0f2-图片.png
                    For example, the results generated by child thread1 need to be written to the database, and used by child thread2.

                    JonBJ SGaistS KroMignonK 3 Replies Last reply
                    0
                    • tovaxT tovax

                      f6eac6e3-dc96-4302-b4a7-013d02ffa0f2-图片.png
                      For example, the results generated by child thread1 need to be written to the database, and used by child thread2.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #29

                      @tovax
                      Most important decision: do you really mean that thread1 must physically write to the database and thread2 must physically (re-)read the data from the database, or do you mean that thread2 can/should read the (changed) data in-memory.

                      tovaxT 1 Reply Last reply
                      0
                      • tovaxT tovax

                        f6eac6e3-dc96-4302-b4a7-013d02ffa0f2-图片.png
                        For example, the results generated by child thread1 need to be written to the database, and used by child thread2.

                        SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #30

                        @tovax from the looks of it you are missing one component: the controller.

                        Your use case is typically one that should rather use MVC rather than just MV.

                        One thing that is not clear is how are you child threads triggered ?

                        Are you creating them on demand on are they long-lived ? In both cases, the suggestions from @KroMignon are good in terms of encapsulation of the threaded components and separation of the storage side.

                        @JonB The one connection per thread rule is rather a constraints of the class design: you shall not use the exact same database connection from different threads in the same spirit as you should not modify GUI object outside the GUI thread.

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

                        JonBJ 1 Reply Last reply
                        1
                        • tovaxT tovax

                          f6eac6e3-dc96-4302-b4a7-013d02ffa0f2-图片.png
                          For example, the results generated by child thread1 need to be written to the database, and used by child thread2.

                          KroMignonK Offline
                          KroMignonK Offline
                          KroMignon
                          wrote on last edited by
                          #31

                          @tovax said in Exception of multi thread reading QSqlTableModel:

                          For example, the results generated by child thread1 need to be written to the database, and used by child thread2.

                          You can solve this with signals/slots:

                          • Client1: you need a signal (or more) for writing result, which can be connected to Main to store in DB and to Client2 to update his parameters.
                          • Client2: you need a signal for writing new position
                          • Main: you need a signal to setup Client1 and another to setup Client2

                          Maybe Client1 and Client2 needs an additional signals to request settings update.
                          But that don't seems to be a very difficult architecture to implement.

                          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                          tovaxT 1 Reply Last reply
                          0
                          • SGaistS SGaist

                            @tovax from the looks of it you are missing one component: the controller.

                            Your use case is typically one that should rather use MVC rather than just MV.

                            One thing that is not clear is how are you child threads triggered ?

                            Are you creating them on demand on are they long-lived ? In both cases, the suggestions from @KroMignon are good in terms of encapsulation of the threaded components and separation of the storage side.

                            @JonB The one connection per thread rule is rather a constraints of the class design: you shall not use the exact same database connection from different threads in the same spirit as you should not modify GUI object outside the GUI thread.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #32

                            @SGaist said in Exception of multi thread reading QSqlTableModel:

                            @JonB The one connection per thread rule is rather a constraints of the class design: you shall not use the exact same database connection from different threads

                            Absolutely, as I said from the start! The question at hand is whether for this user's case he should indeed go for separate connections per thread, or whether he should work on "shared" (somehow) data.

                            Since @Christian-Ehrlicher has not replied to it, could you kindly answer my earlier question, at least for my information:

                            Isn't the following a problem: is it not the case that for a reader accessing data() that calls rowCount() and that can cause physical call to database for fetchMore()?? Or does data()/rowCount() never do that, I can't recall?

                            1 Reply Last reply
                            0
                            • JonBJ JonB

                              @tovax
                              Most important decision: do you really mean that thread1 must physically write to the database and thread2 must physically (re-)read the data from the database, or do you mean that thread2 can/should read the (changed) data in-memory.

                              tovaxT Offline
                              tovaxT Offline
                              tovax
                              wrote on last edited by
                              #33

                              @JonB
                              First of all, the data generated by each child thread must be written to the database in order to prevent sudden power failure. Then, the data generated by each child thread can be shared with each other threads.
                              I just think the unified use of the database is logically simpler, thread2 can read the changed data in memory.

                              1 Reply Last reply
                              0
                              • tovaxT Offline
                                tovaxT Offline
                                tovax
                                wrote on last edited by
                                #34
                                This post is deleted!
                                1 Reply Last reply
                                0
                                • tovaxT Offline
                                  tovaxT Offline
                                  tovax
                                  wrote on last edited by
                                  #35

                                  6458972a-26ed-471a-af0d-ddcadb1f30da-图片.png

                                  1 Reply Last reply
                                  0
                                  • KroMignonK KroMignon

                                    @tovax said in Exception of multi thread reading QSqlTableModel:

                                    For example, the results generated by child thread1 need to be written to the database, and used by child thread2.

                                    You can solve this with signals/slots:

                                    • Client1: you need a signal (or more) for writing result, which can be connected to Main to store in DB and to Client2 to update his parameters.
                                    • Client2: you need a signal for writing new position
                                    • Main: you need a signal to setup Client1 and another to setup Client2

                                    Maybe Client1 and Client2 needs an additional signals to request settings update.
                                    But that don't seems to be a very difficult architecture to implement.

                                    tovaxT Offline
                                    tovaxT Offline
                                    tovax
                                    wrote on last edited by
                                    #36

                                    @KroMignon said in Exception of multi thread reading QSqlTableModel:

                                    Maybe Client1 and Client2 needs an additional signals to request settings update.

                                    Thank you for your detailed steps. The actual application is much more complicated than the block diagram, so I'm worried that this method will need to create too many signal slots.

                                    1 Reply Last reply
                                    0
                                    • tovaxT Offline
                                      tovaxT Offline
                                      tovax
                                      wrote on last edited by
                                      #37

                                      Based on your discussion, I think that creating database connections for each child thread is not my best choice, because the actual situation is much more complicated than the block diagram.

                                      1 Reply Last reply
                                      0
                                      • tovaxT Offline
                                        tovaxT Offline
                                        tovax
                                        wrote on last edited by
                                        #38

                                        In the main thread to create a unique database connection, other child threads interact with the main thread to achieve read/write the database. I know that the signal-slot can easily write data to the database, so what is the best way to read data?

                                        1 Reply Last reply
                                        0
                                        • tovaxT Offline
                                          tovaxT Offline
                                          tovax
                                          wrote on last edited by
                                          #39

                                          2b96e68f-9ecc-4ba1-89a9-51694c3a4344-图片.png

                                          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