c++ - 错误使用条件变量

标签 c++ multithreading

您能否查看一下并提出此代码有什么问题?
它要么在第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时可能不会初始化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++ - 错误使用条件变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59864826/

相关文章:

node.js - NodeJS中的多线程和异步有什么区别

C 多线程 : What is the advantage of a Read Lock (pthread_rwlock_rdlock) if all threads can access it simultaneously?

java - Swing 应用程序线程被 JNA 锁定

java - 用于注册和通知听众的实用程序?

c++ - 如何为程序生成生成可打字的种子?

php - 通过多用户网页重复执行linux程序而不崩溃

c++ - 写入共享内存的频率限制?

c++ - C++中的双指针数组

python - 如何在运行循环/函数时阻止 GUI 卡住?

c++ - 添加可变函数的错误结果