log4cplus 在 fork() 之后会发生什么

What happens with log4cplus after a fork()?

本文关键字:什么 之后 fork log4cplus      更新时间:2023-10-16

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

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

现在我也想在孩子身上使用记录器。它在服务器中运行良好(即我可以在控制台中看到日志输出和设置文件。但是在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 不能在我的环境中使用......

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

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

因此,执行此操作的正确方法是在父级中

关闭,分叉,然后在父级和子级中重新配置。以下函数显示了我们如何处理这种情况。

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