我在服务器上工作,我希望能够使用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就不能在我的环境中使用...
发布于 2015-06-01 15:27:16
正如评论中所提到的,要使所有内容再次正常工作,您需要关闭所有内容并重新配置。
但是,如果您使用的是较新的版本和日志服务器,那么您最终会得到至少一个线程。在这种情况下,fork()不会复制线程,因此调用log4cplus::Logger::shutdown时,如果只是在子进程中调用,就会锁定(它会在子进程中永远等待该线程)。
因此,正确的方法是在父进程中关闭,派生,然后在父进程和子进程中重新配置。下面的函数显示了我们如何处理这种情况。
pid_t fork_child()
{
// shutdown
log4cplus::Logger::shutdown();
pid_t p(fork());
// reconfigure
log4cplus::PropertyConfigurator::doConfigure("snap.properties");
return p;
}https://stackoverflow.com/questions/14657891
复制相似问题