BOOST线程:cout行为

时间:2012-05-28 12:09:39

标签: c++ boost boost-thread

我是Boost线程的新手,我不知道如何从多个线程执行输出。 我有一个简单的boost :: thread从9倒数到1;主线程等待,然后打印“LiftOff .. !!”

#include <iostream>
#include <boost/thread.hpp>
using namespace std;

struct callable {
    void operator() ();
};

void callable::operator() () {
    int i = 10;
    while(--i > 0) {
        cout << "#" << i << ", ";
        boost::this_thread::yield();
    }
    cout.flush();
}

int main() {
    callable x;
    boost::thread myThread(x);

    myThread.join();

    cout << "LiftOff..!!" << endl;

    return 0;
}

问题是我必须在我的线程中使用显式的“cout.flush()”语句来显示输出。如果我不使用flush(),我只会得到“LiftOff !!”作为输出。

有人可以告诉我为什么需要明确使用flush()吗?

4 个答案:

答案 0 :(得分:5)

这不是特定线程相关的,因为cout通常会在每个线程的基础上进行缓冲,并且仅在实现决定时输出 - 因此在线程中输出将仅出现在特定于实现的基础上 - 通过调用flush强制执行要刷新的缓冲区。

这会因实施而异 - 通常是在一定数量的字符之后或发送新行时。

我发现写多个线程或文件的多个线程大多没问题 - 假设输出尽可能原子地执行。这不是我在生产环境中推荐的东西,因为它太难以预测了。

答案 1 :(得分:3)

此行为似乎取决于cout流的操作系统特定实现。我想cout上的写操作会在你的情况下缓冲到某些特定于线程的内存,而flush()操作会强制它们在控制台上打印。我想这是因为endl包括调用flush()操作,并且即使在线程加入之后,main函数中的endl也看不到你的更改。

顺便说一下,将输出同步到线程之间共享的ostream是个好主意,否则你可能会看到它们被混合在一起。我们这样做是为了使用后台线程将日志消息写入关联的ostream的日志类。

答案 2 :(得分:0)

鉴于邮件的长度很短,没有理由在没有刷新的情况下出现任何内容。 (不要忘记std::endl相当于<< '\n' << std::flush。)

答案 3 :(得分:0)

我得到有和没有刷新的问题行为(gcc 4.3.2 boost 1.47 Linux RH5

我假设您的cygwin系统选择实现多个std::cout个关联std::streambuf的对象。我假设这是特定于实现的。 由于flush或endl仅强制缓冲区刷新其OS控制的输出序列,因此线程的cout对象保持缓冲。

在线程之间共享ostream的引用应该可以解决问题。