Logger which writes asynchronously to file from multiple threads I have written a simple logger, AsyncFile, which asynchronously writes data to a file. Since data is going to be written very often (E.g. 10 writes per 30 milliseconds from different threads, my system has a 30ms sync time), I would like to know if:

1. The design makes sense att all? Am I missing something obvious?
2. If the logger is fairly optimal, e.g. that no unneccessary copying takes place.


Basically, my idea is to write data to a shared buffer(m_queue), then copy that data to a tempBuffer from which I then write to a file.

The method write can be called from multiple threads.

I have tested this logger and it seems to work fine, but like all problems involving shared resources, it is hard to know if it is well-designed until you have tried it for a good amount of time. 

AsyncFile.h:

#pragma once

#include &lt;cstdint&gt;
#include &lt;cstddef&gt;
#include &lt;array&gt;
#include &lt;mutex&gt;
#include &lt;condition_variable&gt;

class AsyncFile
{
public:

   AsyncFile();

   void write(std::array&lt;char,40&gt;&amp; buffer);

   void done();

private:

    std::array&lt;char, 160&gt; m_queue;

    std::array&lt;char, 160&gt; tempBuffer;

    std::mutex queue_mutex;

    std::condition_variable cv;

    size_t counter = 0;

    bool readyToCopy = false;

    bool finished = false;

    void logger_thread();

}; // class AsyncFile


AsyncFile.cpp:

#include &lt;thread&gt;
#include &lt;fstream&gt;
#include &lt;string.h&gt;
#include &lt;iostream&gt;
#include &lt;chrono&gt;

void AsyncFile::logger_thread()
{
    FILE* file = fopen("test_file.bin", "wb");

    while(!finished) // Pass "finished" as a parameter by ref? Protect by a mutex?
    {
        std::unique_lock&lt;std::mutex&gt; lk(queue_mutex);
        cv.wait(lk, [&amp;]{return readyToCopy;});

        std::copy(m_queue.begin(), m_queue.end(), tempBuffer.begin());

        readyToCopy = false;
        lk.unlock();

        // Now write to file from the temporary buffer:
        fwrite(&amp;tempBuffer, sizeof(char), sizeof(tempBuffer), file);
    }
    fclose(file);
}

AsyncFile::AsyncFile()
{
      std::thread m_worker(&amp;AsyncFile::logger_thread, this);
      m_worker.detach(); // let the worker thread live on its own.
}

void AsyncFile::done()
{
    finished = true;
}

void AsyncFile::write(std::array&lt;char, 40&gt;&amp; buffer) // 40 should probably be a
                                                    // configurable parameter.
{
   std::lock_guard&lt;std::mutex&gt; guard(queue_mutex);
   std::copy(buffer.begin(), buffer.end(), m_queue.begin() + counter);
   if (counter == 120) // fill the queue, 40 char each time, until we have 160 chars in total. Then
                       // notify the writing thread we are ready.
   {
      counter = 0;
      readyToCopy = true;
      cv.notify_one();
   }
   else
   {
      counter += 40;
   }
}
To make a fast logger you need to 


minimise the use of mutexes.
detach the logging from the writing.
minimise copying
pre-alloc the buffers


no allocs during logging.

make a ring buffer


fixed number of logging
decide what should happen if its full
slightly slower using a dequeue with minimises allocs

use atomic indexes to the (ring) buffer


if your system if fully loaded, you have to log often use the cv or wait until the logger thread gets scheduled by the OS.
use the cv.notice_one where the index is updated if the front is sufficient in front of the back end.



So a few of the things that are issues


The logger_thread blocks further logging while it writes.
The write blocks other threads logging


Running into a mutex that is taken causes a task switch, typically  taking from 1000ns to 22000ns on a x86, nearer the lower if its started again on the same hardware thread.