Exception of multi thread reading QSqlTableModel
-
-
In other words, different threads connect to the same database. When one thread updates the data in the database, how do other threads know that the database has been updated? The method of using Signal-Slots between threads seems troublesome.
@tovax said in Exception of multi thread reading QSqlTableModel:
The method of using Signal-Slots between threads seems troublesome.
Nonetheless this is indeed the paradigm Qt wants you to use! Why do you find it "troublesome"?
Although doubtless he is correct --- he usually is! --- I do not share @SGaist's immediate alacrity to move to separate connections per thread. It may be required, but it could be costly on resources/memory/speed/consistency. You might also consider either working on an in-memory, shared copy of the data already read in, or signals/slots to/from the main thread. It depends on what you are doing where.
-
@JonB said in Exception of multi thread reading QSqlTableModel:
It may be required,
It is required - QSqlDatabase database connection is not thread-safe.
how do other threads know that the database has been updated?
Use signals/slots
The method of using Signal-Slots between threads seems troublesome.
Why? It's much easier than using semaphores and wait conditions.
But still don't see why you need threads in the first place.
-
@tovax said in Exception of multi thread reading QSqlTableModel:
The method of using Signal-Slots between threads seems troublesome.
Nonetheless this is indeed the paradigm Qt wants you to use! Why do you find it "troublesome"?
Although doubtless he is correct --- he usually is! --- I do not share @SGaist's immediate alacrity to move to separate connections per thread. It may be required, but it could be costly on resources/memory/speed/consistency. You might also consider either working on an in-memory, shared copy of the data already read in, or signals/slots to/from the main thread. It depends on what you are doing where.
@JonB said in Exception of multi thread reading QSqlTableModel:
gm Qt wants you to use! Why do you find it "troubles
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.
-
@tovax said in Exception of multi thread reading QSqlTableModel:
then it is necessary to establish signal slot connections from these threads to all other threads.
That's also true when you don't use signals and slots...
-
@JonB said in Exception of multi thread reading QSqlTableModel:
It may be required,
It is required - QSqlDatabase database connection is not thread-safe.
how do other threads know that the database has been updated?
Use signals/slots
The method of using Signal-Slots between threads seems troublesome.
Why? It's much easier than using semaphores and wait conditions.
But still don't see why you need threads in the first place.
@Christian-Ehrlicher said in Exception of multi thread reading QSqlTableModel:
It may be required,
It is required - QSqlDatabase database connection is not thread-safe.
Yes, I was the first person to say that if you want to access a
QSqlDatabase
database connection you must only do so from its owning thread. If you read what I was saying, I was talking about not having multiple database connections, as an alternative.If, for whatever reason, the user wants to have 100 threads running accessing data read from the database, having 100 separate database connections is not an advisable approach. IMHO.
-
@JonB said in Exception of multi thread reading QSqlTableModel:
It may be required,
It is required - QSqlDatabase database connection is not thread-safe.
how do other threads know that the database has been updated?
Use signals/slots
The method of using Signal-Slots between threads seems troublesome.
Why? It's much easier than using semaphores and wait conditions.
But still don't see why you need threads in the first place.
@Christian-Ehrlicher said in Exception of multi thread reading QSqlTableModel:
But still don't see why you need threads in the first place.
The time-consuming trajectory algorithm and real-time motion control algorithm in the application program need to be processed by separate threads, which will use the parameter data in the database.
-
@JonB said in Exception of multi thread reading QSqlTableModel:
gm Qt wants you to use! Why do you find it "troubles
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.
@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
-
@Christian-Ehrlicher said in Exception of multi thread reading QSqlTableModel:
It may be required,
It is required - QSqlDatabase database connection is not thread-safe.
Yes, I was the first person to say that if you want to access a
QSqlDatabase
database connection you must only do so from its owning thread. If you read what I was saying, I was talking about not having multiple database connections, as an alternative.If, for whatever reason, the user wants to have 100 threads running accessing data read from the database, having 100 separate database connections is not an advisable approach. IMHO.
-
@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
@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...
-
@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...
@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.
-
Again: why do you think you need threads for simple reading data from the database? What heaviy computation do you do with those values?
-
Again: why do you think you need threads for simple reading data from the database? What heaviy computation do you do with those values?
@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. -
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.
-
@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.@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 accessingdata()
that callsrowCount()
and that can cause physical call to database forfetchMore()
?? Or doesdata()
/rowCount()
never do that, I can't recall? -
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.
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.
-
@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.@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 dedicatedQThreadPool
to avoid thread creation/destruction and to be able to wait for computation end withQFutureWatcher
.
-
@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 dedicatedQThreadPool
to avoid thread creation/destruction and to be able to wait for computation end withQFutureWatcher
.