我能同时锁定多个变量吗?

7
我是一个有用的助手,可以为您翻译文本。
我正在询问关于多线程的问题。
假设我有两个全局向量,
std::vector<MyClass1*> vec1 

并且。
std::vector<MyClass2*> vec2. 

此外,我有4个线程可以访问vec1vec2。我能否按照以下方式编写代码?

void thread_func()
// this is the function that will be executed by a thread
{
    MyClass1* myObj1 = someFunction1(); 
    MyClass2* myObj2 = someFunction2();

    // I want to push back vec1, then push back vec2 in an atomic way
    pthread_mutex_lock(mutex);
    vec1.push_back(myObj1);
    vec2.push_back(myObj2);
    pthread_mutex_unlock(mutex);
}

for(int i=0; i<4; i++)
{
    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, NULL);
}

我想做的是在vec1上执行push_back,然后在vec2上执行push_back。
我是一个新手,我有一种感觉,即一个互斥锁只能锁定一个变量。换句话说,在pthread_mutex_lock(mutex)和pthread_mutex_unlock(mutex)之间只能放置vec1.push_back(myObj1)或vec2.push_back(myObj2)中的一个。
我不知道我上面的代码是否正确。如果我错了,有人可以纠正我吗?

顺便提一下:您可以考虑使用std::thread(C++11),并将向量作为引用(通过std::ref)传递给线程函数(以避免全局变量)。 - user2249683
2个回答

5

您的代码是正确的。互斥锁是被锁定的对象,而不是变量。您可以锁定互斥锁来保护一段代码,防止多个线程同时执行它,最常见的情况是保护数据,但通常实际上是在保护一段代码。


你是在说关键区域吗?你能给我指一些好的教程吗? - Shawn
1
https://computing.llnl.gov/tutorials/pthreads/#Mutexes 谈论了互斥锁,并说:拥有互斥锁的线程执行的动作往往是更新全局变量。这是一种安全的方式,可以确保当多个线程更新同一个变量时,最终值与只有一个线程执行更新时的值相同。被更新的变量属于“临界区”。 - Ron Kuper
2
如果我可以指出一个潜在问题:push_back()可能会引发异常。在这种情况下,您将失去对互斥量的控制,可能会导致所有线程都被阻塞。在try catch块中执行关键部分。或者改用std::threadsstd::lock_guard() - Christophe
很好的观点@Christophe,总是使用RAII来处理互斥锁,而std::lock_guard也是一个不错的选择。 - Surt

0

是的,你可以这样写,但是有一些技巧你一定要考虑:

  1. 作用域锁 模式用于异常安全和更好的健壮性。这在 this answer 中有很好的解释。
  2. 避免使用全局变量 让优化器为你发挥更聪明的作用。尝试将数据分组到逻辑类中,并在其方法内实现锁定。更小的变量范围还可以给你带来更好的可扩展性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接