2013-02-02 49 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

正如在評論中提到的,爲了使其一切工作,你想關閉一切,並重新配置。

但是,如果您使用的是較新的版本和日誌服務器您最終會得到至少一個線程。在這種情況下,fork()將不會複製該線程,所以如果在子進程中調用log4cplus::Logger::shutdown,它將被鎖定(它永遠在子進程中等待該線程)。

所以正確的方法是通過關閉父母,分岔,然後在父母和孩子中重新配置。以下功能顯示我們如何處理這種情況。

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