【问题标题】:What happens with log4cplus after a fork()?在 fork() 之后 log4cplus 会发生什么?
【发布时间】:2013-02-02 02:08:14
【问题描述】:

我正在使用服务器,我希望能够使用 log4cplus 记录消息。到这里为止没什么太复杂的。

但是,每次收到连接请求时,我都会使用fork() 创建一个子进程。 fork() 是为了确保子进程有自己的数据库连接实例。

现在我也想在孩子中使用 Logger。它在服务器上工作得很好(即我可以在控制台中看到日志输出和我设置的文件。)但在fork() 之后它看起来好像丢失了。

现在有一个简化的概要:

log4cplus::PropertyConfigurator::doConfigure(filename);
log4cplus::Logger l(log4cplus::Logger::getInstance("snap"));
l.log(ll, "Server Started", f_file, f_line); // <<-- works great!
...
listen();
accept();
...
fork();
// if child:
log4cplus::Logger l(log4cplus::Logger::getInstance("snap"));
l.log(ll, msg, f_file, f_line); // <<-- does not work?!

我认为记录器可能会将文件锁定在服务器中,因此孩子们自己无法打开同一个文件。是这样吗?如果是这样,那么 log4cplus 不能在我的环境中使用...

【问题讨论】:

  • 在创建新记录器之前关闭子记录器中的现有记录器实例。
  • 是否可以通过 shutdown() 调用来完成?
  • 好的!那行得通。 shutdown() + 重新配置和 getInstance()。

标签: c++ fork log4cplus


【解决方案1】:

如 cmets 中所述,要使其再次正常工作,您需要关闭所有内容并重新配置。

但是,如果您使用的是较新的版本和 loggingserver,您最终会得到至少一个线程。在这种情况下,fork() 不会复制线程,因此如果只是在子进程中调用 log4cplus::Logger::shutdown 会锁定(它会在子进程中永远等待该线程。)

因此,正确的方法是在父节点中关闭,分叉,然后在父节点和子节点中重新配置。以下函数显示了我们如何处理这种情况。

pid_t fork_child()
{
    // shutdown
    log4cplus::Logger::shutdown();
    pid_t p(fork());
    // reconfigure
    log4cplus::PropertyConfigurator::doConfigure("snap.properties");
    return p;
}

【讨论】:

    猜你喜欢
    • 2016-01-06
    • 1970-01-01
    • 2023-03-26
    • 2011-11-19
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多