How to write entire QVector to a binary file?
-
@jsulm I already use double buffering i.e. I assign twice the amount of memory for the buffer than needed. But I cannot use two separate buffers as these buffers are controlled by the C based specialized functions which are specific to the acquisition device. All I can do is assign the size of the memory to the buffer. The program flow is as follows:
- Assign buffer size
- Start acquisition
- C based function puts data in the buffer and alerts my application through a callback function
- I retrieve data from the buffer to a C array (I cannot retrieve directly to a vector as this step is also controlled by device-specific C function which only accepts a pointer to a C array)
- Now I can do whatever I want with acquired data
So, there is not much choice in terms of the buffer.
Regarding the use of the C array that I use to get data out of the buffer, it is generated on the heap and deleted at the end of the callback function in which I get the data from the buffer.
I could use two different vectors to store data and achieve so-called 'double buffering' from my application's point of view, and I have tried that. But in this case as well the thread is blocked for the time period of writing data to a file.
-
@JonB Yeah I could use mutexes, but I prefer Queued Connection as there is just one
QVector
to be sent to a different thread. I do not useconst QVector<double>&
because I want to depend on Qt's implicit sharing i.e. if theQVector<double>
is changed while I am still using the previousQVector
to write data in my binary file then it would not affect my "Writer" thread. If I would useconst QVector<double>&
then it would refer to the originalQVector
in the main thread and then I would have to useQMutex
to protect read and write operations. This is my function in theWriter
class which inheritsQObject
and is run in a different thread:void Writer::writeData(QVector<double> vec) { ++sweepCount_; // Increament the count to keep track of number of times data vector is written if(isBin_){ // If user selects file type as .bin for(int ii = 0; ii < vec.length(); ++ii) binOut_ << vec[ii]; // binOut_ is a QDataStrem, assigned to a file when the user clicks on Start button } else{ // if the user selects file type as .csv if(vec.length() > 1){ outStream_ << vec[0]; for(int ii = 1; ii < vec.length(); ++ii) outStream_ << seperator_ << vec[ii]; // seperator_ = ',' or ';' depending on QLocale outStream_ << '\n'; } } }
-
Hi,
In what format do you get the data in the callback ?
-
@CJha said in How to write entire QVector to a binary file?:
I do not use const QVector<double>& because I want to depend on Qt's implicit sharing i.e. if the QVector<double> is changed while I am still using the previous QVector to write data in my binary file then it would not affect my "Writer" thread
So that you know, when passing your QVector through Qt::QueuedConnection - which is the default and correct one across threads - your QVector will be copied auto automatically, there will be no share until write. There will be a copy inside your thread
-
@J-Hilk Thanks, one thing which I am not sure about: What would happen if I use
const QVector<double>&
instead ofQVector<double>
, will it still copy the data if the connection type isQt:QueuedConnection
or will it just copy the reference for the vector? -
@CJha said in How to write entire QVector to a binary file?:
will it still copy the data if the connection type is Qt:QueuedConnection or will it just copy the reference for the vector?
In short: Yes they will be copied.
For more details take a look at this => https://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/ -
@CJha
According to @KroMignon's linkThe conclusion from the above results is that we should pass arguments to signals and slots by const reference and not by value. This advice is true for both direct and queued connections. Even if the sender of the signal and the receiver of the slot are in different threads, we should still pass arguments by const reference.
If you have both signal & slot declared with
QVector<double> vec
and you change both to haveconst QVector<double>&
, you reduce 3 copies to 1.Having said that: I do get lost as to what gets copied, aren't we only talking about the
QVector
structure and not the data it references?? -
@CJha said in How to write entire QVector to a binary file?:
If it's a copy then I assume it is always going to be the data
No, because Qt containers use copy-on-write. See https://doc.qt.io/qt-5/implicit-sharing.html