std::cerr,std::clogの違いについて
2017-04-17-20:00
std::cerrについて調べていたところ以下のようなコード
(http://en.cppreference.com/w/cpp/io/cerr)
に行き当たったのですが、その挙動が理解できずに悩んでいます。
ソースコードは以下です。
#include <thread>
#include <iostream>
#include <chrono>
void f()
{
std::cout << "Output from thread...";
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "...thread calls flush()" << std::endl;
}
int main()
{
std::thread t1(f);
std::this_thread::sleep_for(std::chrono::seconds(1));
std::clog << "This output from main is not tie()'d to cout\n";
std::cerr << "This output is tie()'d to cout\n";
t1.join();
return 0;
}
clang version 3.8.0-2ubuntu4 でコンパイルし、実際に手元の環境(Ubuntu16.04)で動かしてみた所出力は以下のようになりました。
This output from main is not tie()'d to cout
Output from thread...This output is tie()'d to cout
...thread calls flush()
cerrはバッファリングを行わず、clogはバッファリングを行うとの認識だったのですが、この出力結果を見るに、clogへの出力はバッファリングされず、mainスレッドの待機命令を無視して真っ先に出力されているように見えます。また、その後に関数f()の一行目が実行され、t1スレッドも待機に入り、先に待機がとけたmainスレッドでcerrにバッファリングされていたメッセージが出力されているように見えます。
何故このような挙動になり、僕の理解はどのように間違っているのでしょうか。
どなたかご存じの方ご教授願います。
21:20
質問投稿の後にも試行錯誤しつつ調べていたのですが、一部解決したのでここに報告させていただきます。
"Output from thread..."よりも"Thid output ..."のほうが早く出力されていたのはf()内一行目ではflushが起きていないためでした。
ここでバッファに溜まったテキストはcerrの手前で吐き出されていますが、これはcerrが呼び出し直後にまずcout.flushを呼び出すためのようです。以下参考URL
(http://en.cppreference.com/w/cpp/io/cerr)
ただバッファリングされるはずのclogがそのまま出力されているのは未だ解決出来ていません。
"\n"による行バッファリングの可能性も指摘していただいたのですが、"\n"を取り除いても出力は行われるのでこれが原因でもないようです。
21:43
clogですが、試行錯誤の結果、既にcoutにバッファリングされているデータのflushは行わないものの、clog自体のflushはしているということがわかりました。「clogはバッファリングをする」という文言の意味を取り違えていたようです。問題解決に協力してくださったmetropolisさん、ありがとうございました。
21:55
clogについてですが、
cppreference.com(信用度が足りないらしくリンクが投稿できないので、サイト名だけで失礼します)
には勝手にflushされない旨が書いてあるのでやはり不可解な挙動のようです。
追加で調べて進展したらまた追記します。
04-18-12:45
解決しました。詳しくはベストアンサーをご覧ください。Hidekiさんありがとうございました。