多线程写入的std ::法院或std :: CERR(multiple threads writin

2019-07-20 09:52发布

我有一个通过cout和CERR写入控制台的OpenMP线程。 当然,这并不安全,因为输出可以交错。 我可以做类似

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

这将是更好,如果能有一个线程安全的版本替换CERR,类似的做法在Valgrind的DRD手动解释( http://valgrind.org/docs/manual/drd-manual.html#drd-manual.effective-使用 ),它涉及到从获得的std :: ostreambuf类。 理想的情况下在最后我只想用我自己的螺纹CERR更换CERR,如简单地说:

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

因为它遇到一个“ENDL”这样的类可以尽快打印到控制台。 我不介意,如果从不同的线程线交错,但各行应该从一个线程只来。

我真的不明白怎么这一切流于C ++的作品,实在是太复杂了。 有没有人这样的类或能告诉我如何创建用于该目的这样一个班?

Answer 1:

正如其他人所指出的,在C ++ 11 std::cout 线程安全的。

但是如果你使用它像

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

用不同的线程,输出仍然可以交错,因为每个<<是一个新的函数调用可以通过另一个线程的任何函数调用preceeded。

为了避免没有交错#pragma omp critical -这将锁定一切-你可以做到以下几点:

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

三个电话写123到流都发生在只有一个线程到本地,非共享的对象,因此不会受到任何其他线程。 那么,只有一个调用共享输出流std::cout ,其中123项已经是固定的顺序,因此不会搞的一团糟。



Answer 2:

您可以使用类似的字符串生成器的方法。 创建一个非模板类:

  • 提供模板化的operator<<插入到该对象
  • 在内部构建成std::ostringstream
  • 转储上破坏的内容

粗糙的方法:

 class AtomicWriter {
    std::ostringstream st;
 public:
    template <typename T> 
    AtomicWriter& operator<<(T const& t) {
       st << t;
       return *this;
    }
    ~AtomicWriter() {
       std::string s = st.str();
       std::cerr << s;
       //fprintf(stderr,"%s", s.c_str());
       // write(2,s.c_str(),s.size());
    }
 };

用于:

AtomicWriter() << "my variable: " << variable << "\n";

或在更复杂的情况:

{
   AtomicWriter w;
   w << "my variables:";
   for (auto & v : vars) {
      w << ' ' << v;
   }
}  // now it dumps

您将需要添加更多的重载如果你想操纵器,您可以用write优于fprintf在析构函数中的原子写 ,或std::cerr ,你可以概括,以使目标被传递给构造( std::ostream /文件描述符/ FILE* ),



Answer 3:

我没有足够的信誉发表评论,但我想我的后除了在AtomicWriter类支持的std :: ENDL,并允许除性病::法院要使用其他流。 这里是:

class AtomicWriter {
    std::ostringstream st;
    std::ostream &stream;
public:
    AtomicWriter(std::ostream &s=std::cout):stream(s) { }
    template <typename T>
    AtomicWriter& operator<<(T const& t) {
        st << t;
        return *this;
    }
    AtomicWriter& operator<<( std::ostream&(*f)(std::ostream&) ) {
        st << f;
        return *this;
    }
    ~AtomicWriter() { stream << st.str(); }
};


Answer 4:

你可以通过继承做到这一点std::basic_streambuf ,并覆盖正确的功能,使其线程安全的。 然后使用这个类为您的流对象。



文章来源: multiple threads writing to std::cout or std::cerr