简体   繁体   English

跨线程同步C ++错误日志文件

[英]Synchronization of C++ Error Log File across thread

Can any one provide a sample code to achieve sync when a particular log file is accessed by multiple threads. 任何人都可以提供示例代码,以便在多个线程访问特定日志文件时实现同步。 I have heard of using a critical section object but not clear on how to use the same. 我听说过使用临界区对象但不清楚如何使用它。

The details of the implementation will vary depending on which platform (Win32, Posix, ...) you are, and on which library you use (QT, boost, ...). 实现的细节将根据您使用的平台(Win32,Posix,...)以及您使用的库(QT,boost,...)而有所不同。 However, the general idea will be the same, as the primitive that you can use have equivalents. 但是,一般的想法是相同的,因为您可以使用的原语具有等价物。

This series of articles should give you a good understanding of the available option on the different platform, and what are the equivalences. 系列文章应该让您对不同平台上的可用选项有一个很好的理解,以及它们的等价性。

With this you should be able to write a CriticalSection class: 有了这个,你应该能够写一个CriticalSection类:

class CriticalSection
{
    // System specific object

public:
    CriticalSection();
    ~CriticalSection();

    void Lock();
    void Unlock();
};

Then, to send data to your log file, you'll acquire the lock, send the data and then release the lock. 然后,要将数据发送到日志文件,您将获取锁定,发送数据然后释放锁定。

static CriticalSection gLogFileCS;
static std::ofstream*  gLogFilePtr;

void SendLogMessage(const char* message)
{
    gLogFileCS.Lock();
    gLogFilePtr->write(message);
    gLogFileCS.Unlock();
}

You should probably use RAII to ensure that you always unlock the CriticalSection when you're done with it. 您应该使用RAII来确保在完成后始终解锁CriticalSection You'll write a CriticalSectionScopeLock class, 你会写一个CriticalSectionScopeLock类,

class CriticalSectionScopeLock
{
    CriticalSection& CriticalSection_;

public:
    CriticalSectionScopeLock(CriticalSection& cs)
    : CriticalSection_(cs)
    {
        cs.Lock();
    }

    ~CriticalSectionScopeLock()
    {
        cs.Unlock();
    }
};

and then the SendLogMessage function can be rewritten like that: 然后可以像这样重写SendLogMessage函数:

void SendLogMessage(const char* message)
{
    CriticalSectionScopeLock lock(gLogFileCS);
    gLogFilePtr->write(message);
}

This can be improved by posting message in a queue (you take the lock when pushing in the queue), and then having another thread writing data to the file. 这可以通过在队列中发布消息(在推入队列时获取锁定),然后让另一个线程将数据写入文件来改进。 This will reduce contention on the lock, as writing to the disk can block the current thread, and it is generally a bad idea to have a thread block while holding a synchronization resource. 这将减少对锁的争用,因为写入磁盘可能会阻塞当前线程,并且在保持同步资源的同时拥有线程块通常是个坏主意。

enum MessageType
{
    MessageQuit,
    MessageLog,
};

struct LogThreadMessage
{
    MessageType type;
    char*       data;
};

static CriticalSection gLogThreadQueueCS;
static std::list< LogThreadMessage > gLogThreadQueue;

void StartupLogThread(const char* filename)
{
    // System specific stuff to create a thread, and have
    // it run the LogThreadLoop function.
}

static void LogThreadLoop(std::ostream& logFile)
{
    for (;;)
    {
        std::list< LogThreadMessage > queue;
        {
            CriticalSectionScopeLock lock(gLogThreadQueueCS);
            queue.swap(gLogThreadQueue);
        }

        while (!queue.empty())
        {
            LogThreadMessage msg = queue.front();
            queue.pop_front();

            switch (msg.type)
            {
                case MessageQuit:
                    return;

                case MessageLog:
                    logFile.write(msg.data);
                    break;
            }
        }

        sleep(10);
    }
}

void PostLogThreadMessage(const LogThreadMessage& msg)
{
    CriticalSectionScopeLock lock(gLogThreadQueueCS);
    gLogThreadQueue.insert(gLogThreadQueue.end(), msg);
}

void SendLogMessage(char* message)
{
    LogThreadMessage msg;
    msg.type = MessageLog;
    msg.data = message;

    PostLogThreadMessage(msg);
}

void StopLogThread()
{
    LogThreadMessage msg;
    msg.type = MessageLog;
    msg.data = message;

    PostLogThreadMessage(msg);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM