void foo ( Bar* bar , void(Bar::*qux)(void) )
{
if ( bar )
{
bar->qux();
}
}
问题是:
bar
可以在其他线程检查后删除。我无法添加互斥锁成员
Bar
以锁定它。
因此我想知道,如果我可以告诉处理器原子地运行这个函数,我该怎么做?我在谷歌上花了很多时间,但没有找到可以理解的手册......
PS Debian,gcc,不允许 Boost,允许C ++11 。
void foo ( Bar* bar , void(Bar::*qux)(void) )
{
if ( bar )
{
bar->qux();
}
}
问题是:
bar
可以在其他线程检查后删除。
我无法添加互斥锁成员Bar
以锁定它。
因此我想知道,如果我可以告诉处理器原子地运行这个函数,我该怎么做?我在谷歌上花了很多时间,但没有找到可以理解的手册......
PS Debian,gcc,不允许 Boost,允许C ++11 。
您想暂时共享对象的所有权,以防止另一个线程将其删除。这是一项工作,用于shared_ptr
在weak_ptr
我们不需要访问它时允许删除:
void foo ( std::weak_ptr<Bar> weak_bar , void(Bar::*qux)(void) )
{
if (std::shared_ptr<Bar> bar = weak_bar.lock())
{
// We now share ownership of the object - it won't be deleted
bar->qux();
}
// We have released ownership - it can now be deleted
}
当然,如果多个线程需要访问对象,你仍然需要同步;这仅解决了问题中指定的删除问题。
您可能希望使用具有共享所有权语义的智能指针(例如shared_ptr
, intrusive_ptr
)来确保对象在您引用它时保持活动状态。
原子方法的概念在 C++ 中并不像在 Java 中那样存在,在 Java 中您可以将方法定义为同步的。在 C++ 中最接近的方法是创建一个 ScopedMutex 类,如下所示:
class ScopedMutex {
public:
ScopedMutex(pthread_mutex *m) : theMutex_(m) {pthread_mutex_lock(theMutex_);}
~ScopedMutex() { pthread_mutex_unlock(theMutex_); }
// Add appropriate copy constructors and operator=() to disallow mutex copy
// Or consider passing in a reference
private:
pthread_mutex *theMutex_;
};
然后在你的函数中像这样使用它:
void foo ( Bar* bar , void(Bar::*qux)(void) )
{
ScopedMutex m(&aMutex); // This mutex must be defined/initialized elsewhere
if ( bar )
{
bar->qux();
}
// The ScopedMutex goes out of scope when the function does,
// thus releasing the lock
}
但这对您没有任何好处,除非您在使用 bar 对象的所有其他方法中使用相同的互斥锁。
当您有一个具有复杂逻辑且有多个返回语句的函数时,作用域互斥锁特别有用,因此您不必手动解锁互斥锁,当函数超出作用域时它将被解锁。
对不起,不行。C++ 没有任何东西可以支持这一点。您不一定需要将互斥锁添加到Bar
,但为了避免它,您可能需要一个包装器Bar
,或按该顺序排列的东西。