2013-02-02 6 views
0

나는 서버에서 작업하고 log4cplus를 사용하여 메시지를 기록 할 수 있기를 원합니다. 여기까지는 아무 것도 복잡하지 않습니다.fork() 후에 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를 사용할 수 없습니다.

+1

새 아이디를 생성하기 전에 자식의 기존 로거 인스턴스를 닫습니다. –

+0

shutdown() 호출을 통해이 작업을 수행 할 수 있습니까? –

+0

오케이! 그게 효과가 있었어. shutdown() + reconfigure 및 getInstance(). –

답변

1

주석에서 언급했듯이 모든 것을 다시 작동 시키려면 모든 것을 닫고 재구성해야합니다.

그러나 최신 버전과 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; 
}