To protect a shared resource, you need the same critical section for all threads. The code is fine except for the constructor and destructor. This code leads to undefined behavior:
FileWorker a; FileWorker b;
becasuse g_criticalSection initialized twice without intermediate deletion. You need to add static member functions to initialize and complete your class.
static void FileWorker::initialize() { InitializeCriticalSection(&g_criticalSection); } static void FileWorker::finialize() { DeleteCriticalSection(&g_criticalSection); }
When you need to synchronize data on each file, the right way is to implement an abstraction on top of your I / O files (HANDLE, FILE * s, std :: fstream, etc.). For instance.
class SyncronizedOutStream { CRITICAL_SECTION cs; std::ofstream ostm; SyncronizedOutStream(const SyncronizedOutStream&); void operator= (const SyncronizedOutStream&); public: explicit SyncronizedOutStream(const std::string& filename) : ostm(filename.c_str()) { InitializeCriticalSection(&cs); } ~SyncronizedOutStream() { DeleteCriticalSection(&cs); } template<typename T> SyncronizedOutStream& operator<< (T x) { ostm << x; return *this; } void lock() { EnterCriticalSection(&cs); } void release() { LeaveCriticalSection(&cs); } };
Instances of this class cannot be copied or assigned, this is important because a critical section must be copied.
source share