简体   繁体   English

将伪锁传递给std :: condition_variable_any :: wait

[英]Passing a dummy lock to std::condition_variable_any::wait

Suppose there are three threads A, B, and C. B and C suspend at a certain point, waiting for A to signal them to continue. 假设有三个线程A,B和C.B和C在某一点暂停,等待A发信号通知它们继续。 Among the thread synchronization facilities provided by standard C++, std::condition_variable seems to best fit in here (though still bad). 在标准C ++提供的线程同步工具中, std::condition_variable似乎最适合这里(尽管仍然很糟糕)。 Since std::condition_variable must be used with a lock, the code for B and C may contain lines like: 由于std::condition_variable必须与锁一起使用,因此B和C的代码可能包含以下行:

{
  std::mutex mut;
  std::unique_lock<std::mutex> lock(mut);
  cond_var.wait(lock);  // cond_var is a global variable of type std::condition_variable`
}

Note that mut is used here not for synchronization purposes at all, but just to fit the signature of std::condition_variable::wait . 注意, mut在这里根本不用于同步目的,只是为了适应std::condition_variable::wait的签名。 With this observation, I'm thinking that maybe we can do better by implementing a dummy lock class, let's say dummy_lock , and replace std::condition_variable with std::condition_variable_any . 有了这个观察,我想也许我们可以通过实现一个虚拟锁类来dummy_lock ,比如说dummy_lock ,并用std::condition_variable替换std::condition_variable_any dummy_lock meets the BasicLockable requirements with all its methods essentially doing nothing. dummy_lock满足BasicLockable要求,其所有方法基本上什么都不做。 Thereby, we get code similar to the following: 因此,我们得到类似于以下代码:

{
  dummy_lock lock;
  cond_var.wait(lock);  // cond_var is a global variable of type std::condition_variable_any`
}

This, if works at all, should be of higher efficiency than the original one. 如果可以的话,这应该比原来的效率更高。 But the question is, does it even work according to the standard (language-lawyers are apt here) ? 但问题是,它是否按照标准运作(语言律师在这里适用) Even if it works, this is by-no-means an elegant solution. 即使它有效,这绝不是一个优雅的解决方案。 So, do any of you folks have better ideas? 那么,你们中的任何人都有更好的想法吗?

You are working on a false premise. 你正在做一个错误的前提。

The mutex does not only protect the condition predicate, it also protects the condition_variable itself. 互斥锁不仅可以保护条件谓词,还可以保护condition_variable本身。

So the mutex should be at the same scope as the condition_variable and all locks should lock that same mutex. 因此,互斥锁应与condition_variable在同一范围内,并且所有锁应锁定相同的互斥锁。

like this: 像这样:

// global scope
std::mutex mut;
std::condition_variable cond_var;

// thread scope
{
  std::unique_lock<std::mutex> lock(mut);
  cond_var.wait(lock);
}

see here: Why do pthreads' condition variable functions require a mutex? 看到这里: 为什么pthreads的条件变量函数需要一个互斥量?

What you're suggesting would be undefined behavior. 你所建议的是未定义的行为。 The section on condition_variable_any leads with, emphasis mine: condition_variable_any上的部分引导着,强调我的:

A Lock type shall meet the BasicLockable requirements (30.2.5.2). Lock类型应满足BasicLockable要求(30.2.5.2)。 [ Note: All of the standard mutex types meet this requirement. [注意:所有标准互斥锁类型都符合此要求。 If a Lock type other than one of the standard mutex types or a unique_lock wrapper for a standard mutex type is used with condition_variable_any, the user must ensure that any necessary synchronization is in place with respect to the predicate associated with the condition_variable_any instance. 如果标准互斥锁类型之一以外的锁定类型或标准互斥锁类型的unique_lock包装器与condition_variable_any一起使用, 则用户必须确保对与condition_variable_any实例关联的谓词进行任何必要的同步。 —end note ] - 尾注]

The BasicLockable requirements themselves don't just describe the interface, they also describe the required semantics: BasicLockable需求本身不只是描述接口,它们还描述了所需的语义:

A type L meets the BasicLockable requirements if the following expressions are well-formed and have the specified semantics (m denotes a value of type L). 如果以下表达式格式正确并且具有指定的语义 (m表示类型L的值),则类型L满足BasicLockable要求。

m.lock()
2 Effects: Blocks until a lock can be acquired for the current execution agent. 2效果:阻止直到可以为当前执行代理获取锁定。 If an exception is thrown then a lock shall not have been acquired for the current execution agent. 如果抛出异常,则不应为当前执行代理获取锁。

If your dummy_lock doesn't actually acquire a lock, it isn't a BasicLockable , and so you fail to meet the premise for condition_variable_any . 如果你的dummy_lock实际上没有获得锁,那么它不是BasicLockable ,因此你无法满足condition_variable_any的前提。 At that point, all bets are off, and you cannot expect wait() to do anything reasonable. 此时,所有赌注都已关闭,您不能指望wait()做任何合理的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用带有std :: condition_variable_any的伪造假锁是否安全? - Is it safe to use a dummy fake lock with std::condition_variable_any? 与std :: condition_variable_any相关的开销是多少 - What is the overhead associated with std::condition_variable_any std :: condition_variable_any是否具有笨拙的语义? - Does std::condition_variable_any have awkward semantics? stc :: condition_variable_any的libc ++实现 - libc++ implementation of std::condition_variable_any VC ++ 11-std :: condition_variable_any与标准不兼容? - VC++ 11 - std::condition_variable_any not compatible with standard? std::condition_variable 和 std::condition_variable_any 有什么区别? - What is the difference between std::condition_variable and std::condition_variable_any? 我是否需要同步std :: condition_variable / condition_variable_any :: notify_one - Do I need to synchronize std::condition_variable/condition_variable_any::notify_one 在使用 stop_token 等待 condition_variable_any 时是否需要拥有请求停止的锁? - Is owning the lock required to request a stop while waiting on a condition_variable_any with stop_token? 在notify_all崩溃后直接删除std :: condition_variable_any - Delete std::condition_variable_any directly after notify_all crashes 与recursive_mutex一起使用时condition_variable_any的行为? - Behavior of condition_variable_any when used with a recursive_mutex?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM