2013-07-23 45 views
0

當我使用file_sink(在boost :: iostreams),然後fork()子進程時,我觀察到一些奇怪的行爲。奇怪的行爲與分叉時提升file_sink

孩子繼續相同的代碼庫,即沒有exec()調用,因爲這是作爲守護進程的一部分完成的。當然,我的完整代碼充分證明了這個過程,但是我省略了那些不重要的步驟以避免這種行爲。

下面的代碼是簡化的例子,演示行爲:

using namespace std; 
namespace io = boost::iostreams; 

void daemonize(std::ostream& log); 


int main (int argc, char** argv) 
{ 
    io::stream_buffer<io::file_sink> logbuf; 
    std::ostream filelog(&logbuf); 
    //std::ofstream filelog; 

    // Step 1: open log 
    if (argc > 1) 
    { 
    //filelog.open(argv[1]); 
    logbuf.open(io::file_sink(argv[1])); 
    daemonize(filelog); 
    } 
    else 
    daemonize(std::cerr); 

    return EXIT_SUCCESS; 
} 


void daemonize(std::ostream& log) 
{ 
    log << "Log opened." << endl; 

    // Step 2: fork - parent stops, child continues 
    log.flush(); 
    pid_t pid = fork(); // error checking omitted 

    if (pid > 0) 
    { 
    log << "Parent exiting." << endl; 
    exit(EXIT_SUCCESS); 
    } 
    assert(0 == pid); // child continues 

    // Step 3: write to log 
    sleep(1); // give parent process time to exit 
    log << "Hello World!" << endl; 
} 

如果我運行此不帶參數(例如,./a.out),以便它記錄到stderr,然後我得到的預期輸出:

Log opened. 
Parent exiting. 
Hello World! 

但是,如果我這樣做./a.out temp; sleep 2; cat temp然後我得到:

Log opened. 
Hello World! 

因此,父母不知何故在分岔後不再寫入文件。這是謎題#1。

現在假設我只是將io::stream_buffer<io::file_sink> logbuf;移到主體之外,以便它是一個全局變量。這樣做,並簡單地運行./a.out給出如前面的情況相同的預期產量,但寫入文件(例如,溫度)現在給出了一個新的令人費解的行爲:

Log opened. 
Parent exiting. 
Log opened. 
Hello World! 

該行寫道:「日誌打開。」在fork()之前,所以我不明白爲什麼它應該在輸出中出現兩次。 (我甚至在fork()之前立即加上了一個明確的flush(),以確保輸出行不是簡單緩衝的,然後在fork()期間複製緩衝區,之後兩個副本最終都刷新到流中......)所以這就是拼圖# 2。

當然,如果我註釋掉整個fork()過程(標記爲「第2步」整個一節),那麼它的行爲與預期兩個文件和stderr輸出,也不管logbuf是否是全局或局部於main()

另外,如果切換filelog是的ofstream代替stream_buffer<file_sink>(參見main()註釋行),那麼它也表現爲預期的兩種文件和stderr輸出,也不管filelog/logbuf是否是全局的或局部的main()

所以它看起來真的,它是產生這些怪異的行爲file_sinkfork()之間的相互作用......如果任何人有什麼可能會造成這些想法,我會很感激的幫助!

回答

0

我想我明白了......爲後代創造這個答案/任何人在這個問題上磕磕絆絆尋找答案。

我在boost 1.40中觀察到這種行爲,但是當我嘗試使用boost 1.46時,所有行爲都以預期的方式在全部個案中:

Log opened. 
Parent exiting. 
Hello World! 

所以我的假設現在的問題是,這竟是一個提振錯誤已修復1.41-1.46之間版本的某個時候。我沒有看到發行說明中的​​任何內容,這些內容對我來說很明顯,他們發現&修復了這個錯誤,但是可能會在發佈說明中討論修復此錯誤的一些根本原因,並且我無法進行連接根本原因和這種情況。

無論如何,該解決方案似乎是安裝升壓版> = 1.46