2

考虑一个接受 100 个数据元素数组的函数,它会将这些数据元素打印到控制台。

现在说我在多核机器上启动该函数的两个线程。由于它是多核机器,因此两个线程很有可能在两个内核上运行。由于它们都需要显示数据,因此存在控制台窗口竞赛。

现在如何在线程之间共享控制台。?

到达第一个的那个std::cout会显示整个数据,停止其他线程。?还是线程之间共享控制台窗口时间。?如果是这样,是什么决定了线程共享的时间量。?

4

4 回答 4

6

不,cout在 C++11 中不是线程安全的。你必须自己安排。

[准确地说,cout它本身是线程安全的,但仅适用于调用本身的实际持续时间,典型的一行cout << x << y << endl;将是对cout对象内成员函数的三个不同调用。因此,您不需要cout功能本身的互斥保护,但您确实需要它来保证调用的“行”cout作为一个单元执行]。

于 2013-09-18T11:06:51.243 回答
2

这取决于您如何访问输入/输出流:

§ 27.2.3 线程安全 [iostreams.threadsafety]

1 除非另有说明 (27.4),否则多个线程对流对象(27.8, 27.9)、流缓冲区对象 (27.6) 或 C 库流 (27.9.2)的并发访问可能会导致数据争用(1.10)。[ 注意:数据竞争导致未定义的行为 (1.10)。——尾注]

2 如果一个线程进行库调用 a 将值写入流,结果,另一个线程通过库调用 b 从流中读取该值,这样不会导致数据争用,则 a 的写入同步与 b 阅读。

还有第 27.4.1 节

多个线程对同步 (27.5.3.4) 标准 iostream 对象的格式化和未格式化输入 (27.7.2.1) 和输出 (27.7.3.1) 函数或标准 C 流的并发访问不应导致数据竞争 (1.10)。[ 注意:如果用户希望避免交错字符,则仍必须同步多个线程对这些对象和流的并发使用。——尾注]

于 2013-09-18T11:19:19.990 回答
0

如果你使用这样的函数:

void justam(){
   std::cout << "One " << "two ";
}

你从 2 个线程调用它,你会得到或多或少有序的“一”和“二”组合。就像您将在 2 个单独的 std::cout 调用中编写它一样,虽然您可能很幸运,并且可以为两个输出安排 1 个线程,但您也可能不那么幸运并最终得到类似:“一个”“一个” “二” “一”。由于其他人的答案涵盖了 C++/标准,并且由于 C++ 或多或少地依赖于操作系统并且线程调度是操作系统的任务,因此下面是对其工作原理的非常好的简短描述:

http://en.wikipedia.org/wiki/Scheduling_%28computing%29

此外,如果您真的很好奇发生了什么,请查看这篇文章以了解 3 种线程模型:

http://en.wikipedia.org/wiki/Thread_%28computing%29#Models

这 2 篇文章将让您了解多线程的工作原理,包括最终是 I/O 资源的输出缓冲区,以及其他答案应该形成对正在发生的事情和预期的完整画面。

于 2013-10-04T14:41:10.390 回答
0

通常不建议在大型程序中使用 cout,人们更喜欢使用专用的日志记录,您可以在其中将输出重定向到您喜欢的位置。

通常,Boost 是一个自然的候选者,它支持线程安全和非线程安全的记录器,并且几乎是标准的。

http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/log/tutorial/sources.html

于 2014-12-21T10:10:47.903 回答