【问题标题】:How to use Locks in the main function directly如何在main函数中直接使用Locks
【发布时间】:2019-11-26 17:36:19
【问题描述】:

在我的主要功能中,我正在尝试实现类似于下面的多线程,

#include <thread>
#include <mutex>
....

int main(int argc, char *argv[])
{
    std::mutex myMutex;

    while(...) {
       //some code
       std::thread t1([=,&myArr](){
          std::lock_guard<std::mutex> lockGuard(myMutex);
          for(int i=0; i<1000; i++) {
              myArr[i] = alpha*(myArr[i] - t*myArr[i-1]) ;
          }
       });

       std::thread t2([=,&myArr](){
           std::lock_guard<std::mutex> lockGuard(myMutex);
           for(int i=1000; i<2000; i++) {
               myArr[i] = alpha*(myArr[i] - t*myArr[i-1]) ;
           }
       });
       t1.join();
       t2.join();

    }

    return 0;
}

当我运行这样的代码时,myArr 数组没有按我的意愿更新。因为比赛条件。并且 ´´´lock_guard´´´ 应该有助于从我的网络搜索中解决这个问题。但是我对如何将其添加到这段代码中感到有些困惑。我尝试直接添加如下:

{
   t1.join();
   std::lock_guard<std::mutex> lockGuard(myMutex);
}
{
   t2.join();
   std::lock_guard<std::mutex> lockGuard(myMutex);
}

但它给出了错误:mycode.cpp:2127: error: binding reference of type 'std::lock_guard::mutex_type& {aka std::mutex&}' to 'const std::mutex' 丢弃限定符 std::lock_guard lockGuard(myMutex);

有什么聪明的方法可以解决这个问题吗?

【问题讨论】:

  • 错误信息和您显示的代码不匹配。请提供您尝试过的实际代码
  • 请创建一个 minimal reproducible example 来复制您的错误,并将其与该示例的完整和完整的构建输出一起使用,并在您收到错误的行上添加 cmets。
  • 如果您尝试将互斥锁添加到您的 lambda,那么您需要通过引用捕获互斥锁。但这会使你的代码复杂的单线程。
  • answer 和 cmets 几乎指出了编译错误,即使使用互斥锁代码执行是顺序的,但我不确定它是否是预期的,但取决于 t1 和 t2 的执行,myArr 中的值可能会改变,因为 myArr[i] 依赖于 myArr[i - 1] 并且 t1 写入 myArr[999] 而 t2 从 myArr[999] 读取。

标签: c++ multithreading locking


【解决方案1】:

您的代码中有两个问题可能会导致编译错误,但它们都可以通过引用捕获互斥锁来解决。就目前而言,您的代码正在尝试按值捕获互斥锁,因为它包含在默认值 = 下。

第一个问题是不能按值捕获互斥锁,因为互斥锁是不可复制的。第二个问题是,即使您可以按值捕获互斥锁,捕获的互斥锁也会在 lambda 主体内为 const,这意味着它无法被锁定。 (事实上​​,你不能用const 引用std::mutex 来做任何事情。)

同样,这两个问题都可以通过引用捕获来解决。 (虽然,生成的代码仍然没有意义,因为它似乎强制两个线程串行运行。)

【讨论】:

  • 是的,我现在明白了。但我希望两个线程并行工作以将 myArr 索引从 0 更新到 1000 和从 1000 到 2000。我该怎么做?它不应该完全像这样。
  • @user3622770 由于两个线程将更新不同的内存位置,因此似乎不需要锁。你应该让它们都运行。
  • @user3622770 如果两个线程都在不同的内存块上操作(即使这些块是同一个数组的一部分),那么实际上没有任何东西被共享。您可能根本不需要互斥锁。除了这里t*myArr[i-1],你可以从第二个街区进入第一个街区(并从第一个街区进入未定义行为的世界)
  • @Brian 是的,这就是问题所在。
猜你喜欢
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
  • 2015-12-12
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多