【发布时间】:2021-10-07 18:07:32
【问题描述】:
我有多个使用“printf”的线程。 “Printf”不是线程安全的。 那么我可以在它周围使用互斥锁来使其线程安全吗? 还是还有并发问题?
// member
std::mutex mtxTcp;
// inside a function
mtxTcp.lock();
printf("Hello %d\n", u16Id);
mtxTcp.unlock();
【问题讨论】:
-
简短回答:当然 - 去吧。更长的答案: 问:您认为“风险”是否值得添加互斥锁?还是“矫枉过正”?问:“线程安全”是指“崩溃的风险”(互斥锁会有所帮助 - 但风险很小),还是“文本可能在不同线程上的并发 printfs 中被打乱”?如果是后者,请务必添加fflush()。另见:stackoverflow.com/a/40186101/421195
-
旁注:将锁定区域放在块内并使用
std::lock_guard或std::scoped_lock。printf不会抛出任何异常或以其他方式导致通过不规则方式退出常规代码流,这并不像让互斥锁锁定那么糟糕,但没有什么比后来有人来添加一个更糟糕的了几行代码就可以了。例如:{ const std::lock_guard<std::mutex> lock(mtxTcp); printf("Hello %d\n", u16Id); } -
还可以考虑创建一个
thread_safe_printf函数并用它替换所有对printf的风险调用。减少代码重复,您可以用对其余代码影响较小的更好的东西替换函数的核心。 -
打印可能会有点慢,一个好的原则是尽可能缩短锁定的持续时间。因此,您还可以将打印命令排队并让另一个线程处理它们。这些方面的东西:onlinegdb.com/QDx2jaxhM(缺点可能是您与程序进度的同步松散,输出可能会滞后)
标签: c++