0

In my code I save data in a binary file, when I save I run the function save() in a different thread. The data that I'm saving are stored in a vector<uint_32>, this vector is used also by others function and I did a copy to avoid conflicts and not desired modification, I think that this isn't the most efficient way to solve this problem so I want ask which is the best way to have this kind of behavior? I was thinking about shared pointers, maybe. here is the code:

inline void write( std::vector<uint32_t > pData ) {
    fThread = std::thread( &FileHandler::writeFile, this, pData );
    fThread.join();
}
inline void writeFile( std::vector<uint32_t>  cVectorCopy ) {
    fwrite( ( char* )&cVectorCopy[0]  , cVectorCopy.size()*sizeof( uint32_t ) , 1, fBinaryFile );
    closeFile();
}
Filburt
  • 17,626
  • 12
  • 64
  • 115
user3050386
  • 139
  • 1
  • 9

3 Answers3

1

Doing

fThread = std::thread( &FileHandler::writeFile, this, pData );
fThread.join();

Is no different than doing

writeFile(pData);

This is because join() is going to block execution of the current thread and wait until the newly created thread returns before allowing the current thread to continue.

You can call detach() which will allow the thread to continue and the data will be written.

As far as what is the best way to write the data of the vector it depends on what size is it going to be and what behavior do you want. You could make a copy if the vector is not that large and then write the copy to the file. If the vector is going to be large then I would suggest either a std::lock_guard() or use an std::atomic type.

As always you should profile to see which way is actually faster for you.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • This is absolutely correct, but does not answer OP's question, that is how to protect the `std::vector` from modification while it's being written. – Quentin Aug 03 '15 at 13:22
0

std::shared_ptr avoid data races for underlying data creation and destruction, not access.
Critical resource (std::vector<uint_32>) needs to be protected with std::mutex or lockfree tools.

Richard Dally
  • 1,432
  • 2
  • 21
  • 38
  • Don't you think that a mutex or a lock check can take more time than a copy? My problem is not the use of memory, but the use of time.In this optic do you think is better do it with just a copy like I did? – user3050386 Aug 03 '15 at 13:22
  • @user3050386 if mootexes don't suit you, you could try with a [COW](http://stackoverflow.com/questions/628938/what-is-copy-on-write) :D -- But all in all, you'll need to profile to know if optimizations work. It's way too dependent on the size and access patterns of your data to answer theoretically. – Quentin Aug 03 '15 at 13:24
0

The right question to ask is why you use a different thread for the save. If it is because threads are nice just forget about it and do the save in main thread. If it is because your app is already multithreaded, you will have to protect accesses to the vector with mutexes to ensure that you read coherent values.

If your data is not too large and the save does not freeze the whole application, just hold the mutex all the time for the save. If this is not acceptable (for performance or User Interface reasons), only hold the mutex while copying the vector in memory to a different location, release the mutex and write asynchronously to disk.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252