std::condition_variable::notify_all() - 我需要一个例子
std::condition_variable::notify_all() - I need an example
我需要一个例子来使用notify_all()方法。因为我不明白它应该如何工作。
每个等待线程都以这样的代码开头:
std::unique_lock<std::mutex> lock(mutex);
condition_variable.wait(lock, [](){return SOMETHING;});
一开始,等待线程需要获取互斥锁。因此,如果有多个等待线程,其余线程将等待锁定互斥锁。那么,如果等待线程卡在锁定互斥锁并且根本不执行方法 wait() 时,使用 notify_all() 的目的是什么?这些线程将逐个唤醒,而不是同时唤醒。
互斥锁保护condition_variable
的内部状态。在condition_variable
上调用wait
会导致互斥锁被解锁。因此,在等待时,线程不拥有互斥锁。
当wait
完成时,在调用wait
返回之前再次(原子方式)获取互斥锁。
线程不是在互斥锁上争用,而是在条件本身上争用。
如果您愿意,您可以在等待回来后立即解锁锁。例如,如果要允许多个线程在某个条件下同步,则可以这样做。您还可以使用此功能来实现信号量。
例:
此代码以 10 个为批次处理内容。请注意,notify_all()
在unlock()
之后:
#include <condition_variable>
#include <mutex>
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <vector>
void emit(std::string const& s)
{
static std::mutex m;
auto lock = std::unique_lock<std::mutex>(m);
std::cout << s << std::endl;
}
std::mutex m;
std::condition_variable cv;
int running_count = 0;
void do_something(int i)
{
using namespace std::literals;
auto lock = std::unique_lock<std::mutex>(m);
// mutex is now locked
cv.wait(lock, // until the cv is notified, the mutex is unlocked
[]
{
// mutex has been locked here
return running_count < 10;
// if this returns false, mutex will be unlocked again, but code waits inside wait() for a notify()
});
// mutex is locked here
++running_count;
lock.unlock();
// we are doing work after unlocking the mutex so others can also
// work when notified
emit("running " + std::to_string(i));
std::this_thread::sleep_for(500ms);
// manipulating the condition, we must lock
lock.lock();
--running_count;
lock.unlock();
// notify once we have unlocked - this is important to avoid a pessimisation.
cv.notify_all();
}
int main()
{
std::vector<std::thread> ts;
for (int i = 0 ; i < 200 ; ++i)
{
ts.emplace_back([i] { do_something(i); });
}
for (auto& t : ts) {
if (t.joinable()) t.join();
}
}
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '