我是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()吗?
答案 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
的引用应该可以解决问题。