我有一個使用的記錄標準COUT,例如多線程應用程序,重定向COUT的每個線程文件管理線程安全記錄
cout << "some text" << endl;
的問題是,該計劃正面臨着一個偶然的碰撞因爲多線程非線程安全地訪問共享cout。
說,我的程序被命名爲prg.exe,我們運行作爲prog.exe> t.log
由個體線程產生被混到了,甚至沒關係,壞的部分是崩潰每當有所有日誌競爭線程在訪問cout時發生了爭用,一個嘗試刷新,另一個嘗試將某些東西放在那裏,導致崩潰。
由於在現有代碼中cout有很多用途,被不同的線程使用,所以很難將所有的cout改爲別的。所以,我想通過以下:
std::streambuf * redirect_output(char * filenm, std::ofstream& filestr)
{
std::streambuf *newsb, *oldsb;
filestr.open(filenm);
oldsb = std::cout.rdbuf(); // back up cout's streambuf
newsb = filestr.rdbuf(); // get file's streambuf
std::cout.rdbuf(newsb); // assign streambuf to cout
return oldsb;
}
void restore_output(std::streambuf * oldsb, std::ofstream& filestr)
{
std::cout.rdbuf(oldsb); // restore cout's original streambuf
filestr.close();
}
void showFileContent(char *filenm)
{
std::ifstream infile;
infile.open(filenm);
//read data from file
cout << "------------- " << filenm << " -------------" << endl;
cout << infile.rdbuf();
infile.close();
}
每個線程,在啓動,試圖調用redirect_output來清點重定向到一個文件,每個線程單獨的文件。例如,如果我們有3個線程,我們有t1.log,t2.log,t3.log ,最後我們調用每個線程的restore_output,最後在main中,我們通過
合併單個日誌文件showFileContent("t1.log");
showFileContent("t2.log");
showFileContent("t3.log");
我的問題是,是否明智和安全地重定向到每個線程的單個日誌文件併合並在主函數的末尾? 我們可以通過單獨的線程在邏輯同步點合併各個日誌文件嗎?
其他選項可以是線程安全的singleton類封裝內置的I/O並使用該單例對象而不是cout例如, SPCL_IOSTREAM :: getOStream()
根據[這個答案](http://stackoverflow.com/a/6374525/596781),你的前提是不正確的。 –