如何轻松地使std :: cout线程安全? [英] How to easily make std::cout thread-safe?

查看:454
本文介绍了如何轻松地使std :: cout线程安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程的应用程序,它大量使用 std :: cout 用于没有任何锁定的日志。在这种情况下,如何轻松添加锁机制,使std :: cout线程安全?

I have a multi-threaded application, which heavily uses std::cout for logging without any locking. In such a case, how to easily add lock mechanism to make std::cout thread-safe?

我不想搜索每次出现的 std :: cout 并添加一行锁定代码。太麻烦了。

I don't want to search for each occurrence of std::cout and add a line of locking code. That is too tedious.

任何更好的做法?

推荐答案

猜测你可以实现你自己的类,它包装 cout 并将互斥体与它关联。该类的运算符<< 将执行三项操作:

I guess you could implement your own class which wraps cout and associates a mutex with it. The operator << of that new class would do three things:


  1. 为互斥创建一个锁,可能阻塞其他线程

  2. 做输出,即对包装执行操作符<< 流和传递的参数

  3. 构造一个不同类的实例,将锁传递给

  1. create a lock for the mutex, possibly blocking other threads
  2. do the output, i.e. do the operator << for the wrapped stream and the passed argument
  3. construct an instance of a different class, passing the lock to that

这个不同的类将保持锁和委托运算符< 到包装的流。第二个类的析构函数最终会破坏锁并释放互斥体。

This different class would keep the lock and delegate operator << to the wrapped stream. The destructor of that second class would eventually destroy the lock and release the mutex.

所以任何输出你写为单个语句,即作为单个序列<< 调用,只要所有输出都通过具有相同互斥量的对象,就会以原子方式打印。

So any output you write as a single statement, i.e. as a single sequence of << invocations, will be printed atomically as long as all your output goes through that object with the same mutex.

让我们调用两个类 synchronized_ostream locked_ostream 。如果 sync_cout synchronized_ostream 的实例,其中包含 std :: cout ,然后序列

Let's call the two classes synchronized_ostream and locked_ostream. If sync_cout is an instance of synchronized_ostream which wraps std::cout, then the sequence

sync_cout << "Hello, " << name << "!" << std::endl;

会导致以下操作:


  1. synchronized_ostream :: operator< 会获取锁

  2. synchronized_ostream :: operator<< 将委托打印Hello到 cout

  3. operator<<<<(std :: ostream& const char *)会输出Hello。

  4. synchronized_ostream :: operator<< 会构造一个 locked_ostream ,并将锁传递给

  5. locked_ostream :: operator<< 会将 name 的打印委托给 cout

  6. 运算符<<(std :: ostream& std :: string)会输出名称

  7. cout 的同一授权发生在感叹号和结尾操纵符

  8. locked_ostream 临时获得破坏,锁被释放

  1. synchronized_ostream::operator<< would aquire the lock
  2. synchronized_ostream::operator<< would delegate the printing of "Hello, " to cout
  3. operator<<(std::ostream&, const char*) would print "Hello, "
  4. synchronized_ostream::operator<< would construct a locked_ostream and pass the lock to that
  5. locked_ostream::operator<< would delegate the printing of name to cout
  6. operator<<(std::ostream&, std::string) would print the name
  7. The same delegation to cout happens for the exclamation point and the endline manipulator
  8. The locked_ostream temporary gets destructed, the lock is released

这篇关于如何轻松地使std :: cout线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆