有条件地使用std :: lock_guard

Al *_*ndy 15 c++ conditional scope locking c++11

我有一个函数,其中语句foo应该在下面执行,lock_guard但仅当指向mutex对象的指针作为参数提供给函数时.否则foo不必受到保护 lock_guard.

我不能使用lock_guard范围内的if,因为当锁将被立即释放if块结束.

所以,这段代码是胡说八道:

bar( std::mutex * optionalMutex = nullptr )
{
   ...
   if ( nullptr != optionalMutex ) {
      std::lock_guard<std::mutex> lockScope( *optionalMutex );
   }          <- Here the lock ends

   foo...     <- foo is not protected when optionalMutex was provided
}
Run Code Online (Sandbox Code Playgroud)

我试过这样的事情:

bar( std::mutex * optionalMutex = nullptr )
{
   ...
   nullptr == optionalMutex ? 0 : std::lock_guard<std::mutex> lockScope( *optionalMutex );

   // this scope should be protected by lock_guard when optionalMutex was provided

   foo...
}
Run Code Online (Sandbox Code Playgroud)

或多或少,对我来说唯一可能的解决方案是重复 foo:

bar( std::mutex * optionalMutex = nullptr )
{
   ...
   if ( nullptr != optionalMutex ) {
      std::lock_guard<std::mutex> lockScope( *optionalMutex );
      foo...
   }  else {
      foo...
   }
}
Run Code Online (Sandbox Code Playgroud)

编译器gcc 4.9.3没有编译第二个例子并抱怨:error: expected primary-expression before 'lockScope'.更新: Superlokkus在他的回答中解释了原因.

但我确实希望避免任何代码重复,因此也避免重复foo.

我的问题:

有一种优雅的方式如何实现这个问题,而不是使用重复foo.我知道,我可以使用lambda函数进行分组, foo但如果有另一个解决方案,我很好奇.

Sup*_*kus 12

这个怎么样?

void bar(std::mutex * optionalMutex = nullptr)
{
        auto lockScope = (optionalMutex == nullptr) ? 
                           std::unique_lock<std::mutex>() 
                         : std::unique_lock<std::mutex>(*optionalMutex);
}
Run Code Online (Sandbox Code Playgroud)

说明:您的编译器在使用您的先前语句时遇到问题,因为您不能突然更改三元?表达式的类型; 即文字0不是a std::lock_guard,反之亦然.所以我将两个分支更改为相同的类型,这里std::unique_lock<std::mutex>因为lock_guard没有设计没有有效的互斥锁.但还是喜欢std::lock_guardstd::unique_lock在简单的情况,因为它会使你的代码更易读.

你的语句也不适用于编译器,即使语法正确,因为变量lockScope只存在于一个分支中.

  • 当然,你也可以用 `!optionalMutex` 代替 `optionalMutex == nullptr`,或者更好的是,反转整个条件。 (2认同)

Pet*_*ker 9

你真正拥有的是两个功能,一个锁定,一个不锁定.第一个可以调用第二个:

void bar() {
    // whatever
}

void bar(std::mutex* mtx) {
    std::lock_guard<std::mutex> lockScope(*mtx);
    bar();
}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这根本不是我的解决方案。我没有提到`foo`是一个函数。我想将其用作代码的同义词。在此代码中,在互斥锁上方定义了使用的局部变量,这些变量不能在您的建议中使用。很抱歉对于这个误会! (2认同)