多线程应用程序中的日志队列

时间:2013-08-14 07:33:44

标签: c++ multithreading

我写了一个网络记录器,它在单独的线程中工作。我们的想法是允许应用程序推送任何数量的数据,并且记录器应该单独处理它而不会减慢主线程的速度。伪代码看起来像:

void LogCoroutine::runLogic()
{
    mBackgroundWorker = std::thread(&LogCoroutine::logic, this);
    mBackgroundWorker.detach();
}

void LogCoroutine::logic()
{
    while (true)
    {
        _serverLogic();
        _senderLogic();

        std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 10ms
    }
}

void LogCoroutine::_senderLogic()
{
    std::lock_guard<std::mutex> lock(mMutex);    

    while (!mMessages.empty() && !mClients.empty())
    {
        std::string nextMessage = mMessages.front();
        mMessages.pop_front();

        _sendMessage(nextMessage);
    }
}

_serverLogic检查套接字是否有新连接(对等体)和_senderLogic进程与消息队列,并将其发送给所有连接的对等体。

最后一个功能:推送消息:

void LogCoroutine::pushMessage(const std::string& message)
{
    std::lock_guard<std::mutex> lock(mMutex);
    mMessages.push_back(message);
}

当包裹不经常发送时,一切都很顺利。应用程序启动时会有一个循环记录大量信息。应用程序挂起5-10秒,没有记录它不会减慢速度。

那么,这个架构的瓶颈在哪里?也许用内置互斥锁推送每条消息是一个坏主意?

2 个答案:

答案 0 :(得分:1)

您的方法基本上是以一定间隔(10毫秒)轮询日志事件。这种方法(实际上忙于等待)不是很有效,因为即使没有任何日志消息,您也总是消耗一些CPU。另一方面,如果新消息到达,则不通知等待线程。

我建议使用某种blocking queue来解决这两个问题。内部阻塞队列具有互斥和条件变量,因此当队列为空时,消费者线程正在等待(不忙循环!)。我认为你的用例非常适合阻塞队列。您可以基于互斥+条件变量轻松实现自己的队列。

使用互斥锁推送每条消息并不是一个坏主意,无论如何都必须同步它。我只是建议摆脱民意调查。

答案 1 :(得分:0)

See this example: 如何为生产者和工作队使用工作队列消费者(1对多)。很好地解释了。