本文介绍了多个线程写入std :: cout或std :: cerr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些OpenMP线程,它们通过cout和cerr写入控制台.这当然是不安全的,因为可以交错输出.我可以做类似的事情

I have OpenMP threads that write to the console via cout and cerr. This of course is not safe, since output can be interleaved. I could do something like

#pragma omp critical(cerr)
{
   cerr << "my variable: " << variable << endl;
}

最好将cerr替换为线程安全版本,类似于valgrind DRD手册( http://valgrind.org/docs/manual/drd-manual.html#drd-manual.effective-use ),其中涉及到来自std :: ostreambuf的类.理想情况下,最后我只用自己的螺纹cerr代替cerr,例如简单地:

It would be nicer if could replace cerr with a thread-safe version, similar to the approach explained in the valgrind DRD manual (http://valgrind.org/docs/manual/drd-manual.html#drd-manual.effective-use) which involves deriving a class from std::ostreambuf. Ideally in the end I would just replace cerr with my own threaded cerr, e.g. simply:

tcerr << "my variable: " << variable << endl;

此类可能在遇到"endl"后立即打印到控制台.我不介意来自不同线程的行是否交错,但每一行应仅来自一个线程.

Such a class could print to the console as soon as it encounters an "endl". I do not mind if lines from different threads are interleaved, but each line should come only from one thread.

我不太了解C ++中的所有流式传输如何工作,这太复杂了.有没有人有这样的课程,或者可以告诉我如何为此目的创建这样的课程?

I do not really understand how all this streaming in C++ works, it is too complicated. Has anybody such a class or can show me how to create such a class for that purpose?

推荐答案

正如其他人指出的那样,在C ++ 11中,std::cout 是线程安全的.

As others pointed out, in C++11, std::cout is thread-safe.

但是,如果您喜欢使用它

However if you use it like

std::cout << 1 << 2 << 3;

具有不同的线程,由于每个<<是一个新的函数调用,因此在另一个线程上的任何函数调用都可以作为前导,因此输出仍然可以交错.

with different threads, the output can still be interleaved, since every << is a new function call which can be preceeded by any function call on another thread.

为避免与不相交插入#pragma omp critical(会锁定所有内容),您可以执行以下操作:

To avoid interleaving without a #pragma omp critical - which would lock everything - you can do the following:

std::stringstream stream; // #include <sstream> for this
stream << 1 << 2 << 3;
std::cout << stream.str();

将123写到流的三个调用仅发生在一个线程中,该线程到达本地非共享对象,因此不受任何其他线程的影响.然后,只有一个对共享输出流std::cout的调用,其中项123的顺序已经固定,因此不会弄乱.

The three calls writing 123 to the stream are happening in only one thread to a local, non-shared object, therefore aren't affected by any other threads. Then, there is only one call to the shared output stream std::cout, where the order of items 123 is already fixed, therefore won't get messed up.

这篇关于多个线程写入std :: cout或std :: cerr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 15:32