多线程应用程序中的日志队列
Log queue in multithreaded application
我写了一个网络记录器,它在单独的线程中工作。这个想法是允许应用程序推送任何数量的数据,记录器应该单独处理它,而不会减慢主线程的速度。伪代码看起来像:
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秒,不记录也不会减慢速度。
那么,这个体系结构的瓶颈在哪里呢?也许将每个消息都插入互斥锁是个坏主意?
您的方法基本上是以一定的间隔(10ms)轮询日志事件。这种方法(实际上是忙于等待)的性能不是很好,因为即使没有任何日志消息,您也总是会消耗一些CPU。另一方面,如果新消息到达,您不会通知等待线程。
我建议使用某种阻塞队列来解决这两个问题。内部阻塞队列有互斥锁和条件变量,所以当队列为空时,使用者线程正在等待(而不是忙于循环!)。我认为您的用例非常适合阻塞队列。基于互斥+条件变量,您可以非常容易地实现自己的队列。
用互斥体推送每条消息并不是一个坏主意,无论如何都必须同步它。我只是建议取消投票。
请参阅此示例:如何使用生产者的工作队列&消费者(1对多)。解释得很好。
相关文章:
- boost::进程间消息队列引发错误
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- Android NDK传感器向事件队列报告奇怪的间隔
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 使用2个键的cpp-stl::优先级队列排序不正确
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 在一个读写器队列中,我可以用volatile替换原子吗
- 为什么我的多线程作业队列崩溃
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 使用"Task"函数指针队列定义作业管理器
- 在c++队列中使用pop和visit实现线程安全
- 为什么我需要C++中不同的排序格式来对这个USACO代码上的数组和优先级队列进行排序
- 打印优先级队列
- 共享队列的线程安全
- 带自定义比较器的最小优先级队列
- 在 Vulkan Qt 中获取队列系列
- 堆栈和队列是否像C++中的数组一样传递?
- 多线程应用程序中的日志队列