Search code examples
c++boost-threadofstream

ofstream write from multiple boost threads - g++ and vs2008


Using the boost thread library I pass the open ofstream file to each thread as a reference, after half the threads write there is some kind of crash and the program terminates. My assumption is the function reaches the end, closes the file and the remaining threads are trying to write to a closed file. As a test, I added a join statement for the last thread and more of the threads managed to write to file. My experience mutithreading is 2 days - yesterday I got the boost library built and not much more experience in c++ or any language.

I read through the "Questions that may already have your answer" but none answer this question. There are so many posts addressing versions of this problem and just as many approaches to the solution - that is seems more like overthinking and there is a clean way to ensure all the threads have finished before the file closes and that the writes from each thread are buffered in a queue to prevent write clashes.

Some possible solutions:

  • Rather than pass an open file, pass the file reference and let each thread open the file, append, and close ofstream myfile("database", ios::out | ios::app); - from this posted solution "How do I add..."; this did not work

  • Reading through the boost thread documentation, there is a join_all() function but compiled in vs2008 from a boost 1.53.0 version, "error C2039: 'join_all' : is not a member of 'boost::thread'"

  • Use boost mutex or locks this explanation seems like it is the asnwer, but I'd first like to know if the crash is due to multiple writes conflicting or the file closes before the threads have finished writing.

  • This c++ ostream::write page referenced multithreading, but just states that there are no guarantees

  • This one states something about boost::thread and boost::function work like no other, but reviewing the boost::function literature did not help explain what the comment means

  • Back to if this is a problem with waiting for all threads to complete and not a write clash, this discussion provides a solution that requires storing all the threads, and calling join()

  • This discusses the windows specific WaitForMultipleObjects but this is windows specific - the last solution in this post sounds like the answer but it has no votes and I cannot tell if it is windows specific or not.

  • Buffer everything to memory and write-out in a separate function - this solution is in C# but the approach seems plausible. The specifics of their discussion don't make sense to me.

  • create threads in a loop - seems to have the clearest review; solved using boost::thread_group method given in this thread

  • There are more forum discussions but they sound like more versions of the previous examples

I'd like a solution that works in both windows and linux; my intuition is to pass the file reference and let each thread append to the file.


Solution

  • What results do you expect to see after uncoordinated writes from several threads to the same stream? That will be garbage after all, even if the stream did survive this torture... You will need to implement some kind of coordination between the writes.