我是多线程编程的新手。所以在我的情况下,我有一个boost multi_index
容器,可以同时从多个线程到达。我正在执行一些搜索和插入操作。
因此,当搜索以索引开头时,我不希望另一个线程插入新值。因为它可以改变索引和质量。所以我必须使用互斥锁。
为此目的,有许多人使用boost scoped_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开始获取锁,这意味着从程序A开始。如果我将boost::mutex::scoped_locklock(mutex);
代码放到标有******* 1 ********
的地方,它也会锁定procedure B
和procedure search
中的流程或我是否必须将锁定置于B
和search
内? (到标有2& 3的地方)。哪个是正确的地方1,2,3或所有?
顺便说一下,我的应用程序是单一作家和多种读者类型。因此shared_lock
在我的案例中有很大差异,或者可以与scoped_lock
一起使用吗?
注意:我在visual sturdio 2008环境中使用visual c ++
...谢谢
答案 0 :(得分:1)
作用域锁定的范围在范围内,因此:
X(){
}
Y(){
升压::互斥::的scoped_lock(MUT);
X();
}
表示当你调用Y()时,互斥锁也会在执行X期间被锁定,但只有当从Y调用X时才会被锁定。
答案 1 :(得分:1)
boost::mutex::scoped_lock lock(mutex);
创建具有自动存储的对象(a.k.a是常规局部变量)。此对象锁定在创建时传递的互斥锁,并在销毁时解锁它。由于对象具有自动存储功能,因此当它超出范围时会被破坏(因此互斥锁会被解锁)。
具体来说,这意味着是,如果您将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
}