滥用条件变量
Misuse of conditional variable
您能否查看并建议此代码有什么问题? 它要么在第 21 行崩溃 (cond_var_.wait(lock(; 在 gc_thread_proc((( 中,要么在第 56 行(lock.lock((; 在 release((( 中锁定。
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <thread>
#include <vector>
#include <iostream>
class stream {
std::deque<int> pending_cleanups_;
std::mutex mut_{};
bool continue_{true};
std::thread gc_worker_;
std::condition_variable cond_var_;
void gc_thread_proc() {
while (true) {
std::vector<int> events_to_clean;
std::unique_lock<std::mutex> lock(mut_);
while (pending_cleanups_.empty() && continue_) {
cond_var_.wait(lock);
}
if (!continue_) {
break;
}
std::move(std::begin(pending_cleanups_), std::end(pending_cleanups_), std::back_inserter(events_to_clean));
pending_cleanups_.clear();
}
}
public:
explicit stream() : gc_worker_(&stream::gc_thread_proc, this) {}
void register_pending_event(int val) {
{
std::lock_guard<std::mutex> lock_guard(mut_);
pending_cleanups_.push_back(val);
}
cond_var_.notify_one();
}
void release() {
std::unique_lock<std::mutex> lock(mut_);
if (!continue_) {
return;
}
continue_ = false;
lock.unlock();
cond_var_.notify_one();
gc_worker_.join();
lock.lock();
pending_cleanups_.clear();
}
~stream() { release(); }
};
int main() {
int N=100000;
while(N--) {
std::cout << ".";
stream s;
}
std::cout << "ok";
return 0;
}
更改成员的顺序会使此问题消失 - 当cond_var_放在gc_worker_问题不会重现之前时。但我想它不能修复它只是以某种方式隐藏它......
非静态数据成员按类定义中的声明顺序初始化:https://en.cppreference.com/w/cpp/language/initializer_list
3) Then, non-static data members are initialized in order of declaration in the class definition.
在您的情况下,由于 std::thread 成员已初始化为在其构造函数中开始执行,因此在 gc_thread_proc 中使用 cv 时可能不会初始化。拥有 std::thread 成员的一种命令方法是在类构造器中移动分配它,即
class stream {
std::thread gc_worker_;
std::condition_variable cond_var_;
public:
stream(): {
gc_work = std::move(std::thread(&stream::gc_thread_proc, this));
}
};
相关文章:
- 基于模板值的条件变量
- 没有超时的C++条件变量
- 在条件变量中触发错误信号的频率是多少
- 使用不变量来确定二分搜索中的边界条件
- 在通知提升间处理条件变量时未按住锁会导致问题
- 通知条件变量后使用互斥锁
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 滥用条件变量
- 升压插值条件变量可以虚假唤醒吗?
- 根据模板类型有条件地删除变量
- 子线程中的条件变量等待停止主线程中的执行
- 如何使用 SFINAE 在方法调用中有条件地定义变量?
- 条件变量基本示例
- 正在连接的等待条件变量的线程会发生什么情况?
- C++11如何在1个线程中使用条件变量处理2个线程安全队列
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 为什么在同一条件变量上使用多个互斥锁会使此代码崩溃?
- 条件变量:wait_for.gcc错误
- 如何"stop"正在等待条件变量的分离线程?
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取