本篇内容主要讲解“C++为什么不要拿着锁调用未知代码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++为什么不要拿着锁调用未知代码”吧!
CP.22:永远不要拿着锁调用未知代码(例如callback)
If you don't know what a piece of code does, you are risking deadlock.
如果你不知道一段代码会做什么,就会面临死锁的风险。
Example(实例)
void do_this(Foo* p)
{
lock_guard<mutex> lck {my_mutex};
// ... do something ...
p->act(my_data);
// ...
}
如果你不知道Foo::act会做什么(可能这是一个虚函数,会调用某个派生类的成员),它也可能(递归)调用do_this并引发my_mutex发生死锁。它也可能对另外的mutex加锁并无法在合理的时间内返回,从而导致所有调用do_this的代码发生延迟。
Example(示例)
调用未知代码引起问题的常见例子是调用的函数试图重新访问一个处于锁定状态的对象。这样的问题通常可以通过使用可重入的recursive_mutex解决。例如:
recursive_mutex my_mutex;
template<typename Action>
void do_something(Action f)
{
unique_lock<recursive_mutex> lck {my_mutex};
// ... do something ...
f(this); // f will do something to *this
// ...
}
If, as it is likely, f() invokes operations on *this, we must make sure that the object's invariant holds before the call.
如果,由于f()可能调用针对*this的操作,我们必须保证调用之前的对象不变式能够维持。
Enforcement(实施建议)
Flag calling a virtual function with a non-recursive mutex held
标记调用一个持有不可重入mutex的虚函数的情况。
Flag calling a callback with a non-recursive mutex held
标记调用一个持有不可重入mutex的回调函数的情况。
到此,相信大家对“C++为什么不要拿着锁调用未知代码”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。