当前位置: 首页 > 知识库问答 >
问题:

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

尉迟子民
2023-03-14
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);
    }
}
void LogCoroutine::pushMessage(const std::string& message)
{
    std::lock_guard<std::mutex> lock(mMutex);
    mMessages.push_back(message);
}

那么,这种架构的瓶颈在哪里?也许推送每条带有互斥体的消息是个坏主意?

共有1个答案

司空鸿熙
2023-03-14

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

我建议使用某种阻塞队列来解决这两个问题。内部阻塞队列有互斥体和条件变量,这样使用者线程就在等待(而不是忙循环!)而队列为空。我认为您的用例对于阻塞队列来说是非常理想的。您可以真正轻松地基于互斥+条件变量实现自己的队列。

用互斥体推送每个消息不是一个坏主意,无论如何你都要同步它。我只是提议取消投票。

 类似资料:
  • 问题内容: 在多线程应用程序中如何使用Hibernate(例如,每个客户端连接在服务器上启动它自己的线程)。 EntityManager应该仅由EntityManagerFactory创建一次,例如: 还是我必须为每个线程以及关闭EM的每个事务重新创建实体? 我的CRUD方法如下所示: 我要不要每次都跑?还是因为每个人都使用自己的缓存创建自己的EntityManager实例而使我陷入麻烦了? 问题

  • 问题内容: 自两年以来,我一直在使用java(Servlets,JSPs)进行Web应用程序开发。在那两年中,我从不需要在任何项目中使用(明确地- 众所周知,servlet容器使用线程为不同的请求提供相同的servlet)。 但是,每当我参加Web开发人员职位(java)的面试时,就会有几个与java中的线程相关的问题。我知道Java线程的基础知识,因此回答问题不是问题。但是有时我会感到困惑,是否

  • 我有一个nodejs应用程序,它只不过是一个使用微软botbuilder框架构建的机器人。我创建了azure应用程序服务来托管此应用程序。我想找到一种方法,将所有应用程序日志和web服务器日志(如果可能的话)持久化到某个持久化存储中。就像本地web应用程序一样,我们可以在应用程序服务器上查找日志 在做了一些研究之后,我找到了微软关于这方面的官方文件,但看起来它有以下局限性。 我们不能使用应用程序服

  • 我知道和都在/usr/local/Spark/jars中,尽管在pom.xml中排除了这些jar,但Spark很可能引用了这些jar,因为如果删除它们,在spark-submit的运行时会给出一个ClassNotFoundException。 我的问题是:有没有一种方法可以在我的应用程序中使用Logback实现本机日志记录,同时保留Spark的内部日志记录功能。理想情况下,我希望将我的日志返回应用

  • 我在一个用C语言编写的多线程服务器应用程序上工作,并在嵌入式Linux上执行。一个线程(我称之为通信线程)应该处理所有套接字I/O(发送和接收消息)。依赖于接收到的消息,通信线程将消息发送到另一个线程(例如Thread)。Controller-Thread)处理所需的序列。控制器线程在序列的末尾创建返回消息。此消息被写回通信线程,该线程应该将它们传输到客户端。 这两个线程之间的通信是通过队列实现的

  • 我对多租户非常陌生。我们有一个基于Java、Spring、Hibernate/JPA等的应用程序,它不支持多租户。 现在,我们要将该应用程序转换为多租户应用程序。我读过关于多租户的文章,甚至用独立的模式方法编写了一个独立的应用程序。链接指的是这里。 我想到了日志部分,现在肯定会改变,因为日志文件现在将按租户(客户端)维护。因此,对于每个租户,将有一个单独的日志文件。此外,另一个租户不应访问特定租户