【问题标题】:Can I lock multiple variables simultaneously?我可以同时锁定多个变量吗?
【发布时间】:2015-05-17 16:21:37
【问题描述】:

我在问一个关于多线程的问题。

假设我有两个全局向量,

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 >。

我是新手,我感觉只能用互斥锁锁定一个变量。换句话说,只能放 vec1.push_back(myObj1)vec2.push_back(myObj2)pthread_mutex_lock(mutex)pthread_mutex_unlock(mutex) 之间。

我不知道我上面的代码是否正确。如果我错了,有人可以纠正我吗?

【问题讨论】:

  • 旁注:您可以考虑使用 std::thread (C++11) 并将向量作为参考(通过 std::ref)传递给线程函数(以避免全局变量)。

标签: c++ multithreading pthreads


【解决方案1】:

您的代码是正确的。互斥锁是被锁定的东西,而不是变量。您锁定互斥锁是为了保护一段代码不被多个线程执行,最常见的是为了保护数据,但通常它实际上是在保护一段代码。

【讨论】:

  • 你说的是临界区吗?你能指点我一些好的教程吗?
  • computing.llnl.gov/tutorials/pthreads/#Mutexes 谈到互斥体,并说: 拥有互斥体的线程执行的操作通常是更新全局变量。这是一种安全的方法,可以确保当多个线程更新同一个变量时,最终值与只有一个线程执行更新时的值相同。正在更新的变量属于“临界区”。
  • 如果我能指出一个潜在的问题:push_back() 可能会引发异常。在这种情况下,您将失去对可能对所有线程保持阻塞的互斥锁的控制。在 try catch 块中执行关键部分。或者改用std::threadsstd::lock_guard()...
  • 好点@Christophe,总是使用 RAII 作为互斥锁,因为 std::lock_guard 无论如何都在那里。
【解决方案2】:

是的,你可以这样写,但你绝对应该考虑一些技巧:

  1. Scoped lock 模式,通常用于异常安全和更好的鲁棒性。 这在this answer 中有很好的解释
  2. 避免使用全局变量,让优化器更智能地为您工作。尝试将数据分组到逻辑类中并在其方法中实现锁定。更小的变量范围还可以为您提供更好的可扩展性。

【讨论】:

    猜你喜欢
    • 2020-09-02
    • 1970-01-01
    • 2013-12-06
    • 2021-04-16
    • 2022-11-26
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多