问题描述
我有一个多线程的应用程序,它大量使用 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:
- 为互斥创建一个锁,可能阻塞其他线程
- 做输出,即对包装执行操作符
<<
流和传递的参数 - 构造一个不同类的实例,将锁传递给
- create a lock for the mutex, possibly blocking other threads
- do the output, i.e. do the operator
<<
for the wrapped stream and the passed argument - 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;
会导致以下操作:
-
synchronized_ostream :: operator<
会获取锁 -
synchronized_ostream :: operator<<
将委托打印Hello到cout
-
operator<<<<(std :: ostream& const char *)
会输出Hello。 -
synchronized_ostream :: operator<<
会构造一个locked_ostream
,并将锁传递给 -
locked_ostream :: operator<<
会将name
的打印委托给cout
-
运算符<<(std :: ostream& std :: string)
会输出名称 -
cout
的同一授权发生在感叹号和结尾操纵符 -
locked_ostream
临时获得破坏,锁被释放
synchronized_ostream::operator<<
would aquire the locksynchronized_ostream::operator<<
would delegate the printing of "Hello, " tocout
operator<<(std::ostream&, const char*)
would print "Hello, "synchronized_ostream::operator<<
would construct alocked_ostream
and pass the lock to thatlocked_ostream::operator<<
would delegate the printing ofname
tocout
operator<<(std::ostream&, std::string)
would print the name- The same delegation to
cout
happens for the exclamation point and the endline manipulator - The
locked_ostream
temporary gets destructed, the lock is released
这篇关于如何轻松地使std :: cout线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!