堆栈展开真的需要锁吗?
Posted
技术标签:
【中文标题】堆栈展开真的需要锁吗?【英文标题】:Does stack unwinding really require locks? 【发布时间】:2014-10-08 12:50:35 【问题描述】:我一直在使用 mutrace 分析我的代码并得到以下有趣/令人担忧的结果:
Mutex #1260690 (0x0x7f87bc8eea40) first referenced by:
/usr/lib/mutrace/libmutrace.so(pthread_mutex_lock+0x49) [0x7f87be0b76b9]
/lib/x86_64-linux-gnu/libgcc_s.so.1(_Unwind_Find_FDE+0x26) [0x7f87bc6eb0e6]
mutrace: Showing 10 most contended mutexes:
Mutex # Locked Changed Cont. tot.Time[ms] avg.Time[ms] max.Time[ms] Flags
1260690 19066789 1509831 109753 3600.883 0.000 0.226 M-.--.
_Unwind_Find_FDE
似乎必须处理堆栈展开。
我的应用程序是高度多线程的,具有非常严格的延迟要求,因此我想尽可能轻松地消除这种情况。是否有任何编译器或环境设置可以用来摆脱这个函数调用,而无需重写我的代码?我们确实在部分流控制中使用了异常(可能是不明智的),但要解决这个问题需要很大的重构工作。
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
【问题讨论】:
“我们确实在部分流程控制中使用了异常”然后你必须付出这个代价(你很幸运没有人向你的窗户扔石头哈哈) 不幸的是,我认为您将不得不纠正您的错误,并且不要在热路径中使用异常来控制流量。其他任何东西都是黑客攻击。 异常应该不是正常程序流程的一部分,它们应该是异常。如果你抛出异常,你严格的延迟要求就不会那么严格,因为堆栈展开通常效率不高。 正常的 C++ 约定是在展开堆栈时自动调用对象析构函数。我的水晶球说你只是看到了解决这个问题的管道。 @James:在摘要中,我同意。但是,如果您与 other 线程交互的“单线程”锁定了由类控制的互斥锁的资源,那么我希望类析构函数尝试清理资源,这就是你可能会遇到互斥体。 【参考方案1】:如果您需要低延迟,请停止使用异常。
【讨论】:
如果不抛出异常,它们不会影响运行时。例外情况下可以安全地实现低延迟。 如果“慢”异常超出您的延迟要求,请停止使用它们。一个好的实现不需要有“慢”的例外。如果你的实现不好,那么,好吧,... @AlexShtof “我们确实在部分流程控制中使用了异常”。这个答案是 100% 正确的。当您将异常用于它们并非专门设计用于处理的事情时,您不能抱怨异常的延迟。以上是关于堆栈展开真的需要锁吗?的主要内容,如果未能解决你的问题,请参考以下文章