我对多线程编程有点陌生。因此,就我而言,我有一个 boost multi_index 容器,可以同时从多个线程访问它。我正在执行一些搜索和插入操作。
因此,当搜索从索引开始时,我不希望另一个线程插入新值。因为它可以改变索引并把东西集中起来。所以我必须使用互斥锁。
很多人使用boostscoped_lock
来达到这个目的。我的问题只是 scoped_lock
的“范围”是什么?
假设我有一个这样的函数:
void A ()
{
myData data;
// prepare data here
// ******* 1 ********
B(data); // assume this perform some operations
}
void B (myData data)
{
// do some stuff with data
// ******* 2 ********
search(data);
}
void search(myData data)
{
// ******* 3 ********
// start searching the data here
}
所以我想从进程的开头获取锁,这意味着从过程 A 获取锁。如果我将我的 boost::mutex::scoped_locklock(mutex);
代码放在标记为 ******** 1 ********
是否也锁定 procedure B
和 procedure search
中的进程code> 还是我必须在 B
和 search
内部加锁? (到标有2和3的地方)。哪个是正确的位置 1、2、3 还是全部?
顺便说一句,我的应用程序是单作者和多读者类型。所以 shared_lock
在我的情况下有很大不同,或者可以使用 scoped_lock
吗?
注意:我在 Visual sturdio 2008 环境中使用 Visual C++
谢谢...
最佳答案
boost::mutex::scoped_lock lock(mutex);
创建一个具有自动存储功能的对象(也称为常规局部变量)。该对象会锁定您在创建时传递给它的互斥锁,并在销毁时将其解锁。由于该对象具有自动存储功能,因此当它超出范围时,它会被销毁(因此互斥锁会被解锁)。
具体来说,这意味着是,如果您将上面的scoped_lock语句放在******** 1 ********
标记处在您的代码中,互斥量将一直保持到 A()
返回,因此 B 的执行也将受到锁的保护(在本上下文中)。
void A ()
{
myData data;
// prepare data here
boost::mutex::scoped_lock lock(mutex);
// whatever happens from here ....
doSomeStuff();
B(data); // assume this perform some operations
doMoreStuff();
// ... to here is protected by the lock
}
这个编程习惯被命名为 RAII,即“资源获取即初始化”,您可以在这里了解更多信息:What is meant by Resource Acquisition is Initialization (RAII)?
旁注:从 C++11 开始,STL 现在包含互斥体和锁,因此您不需要为此使用 boost。等效的语句是:
std::mutex a_mutex;
{
std::lock_guard<std::mutex> a_lock(a_mutex);
// mutex is locked until the end of this scope
}
关于c++ - scoped_lock 的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21874083/