emplace_back 包含互斥锁的对象

emplace_back an object containing a mutex

我正在尝试创建执行搜索的线程向量。这是我 SearchThread class.

的重要内容
Class SearchThread {

        explicit SearchThread(int t_id) {
            id = t_id;
            run = true;

            thread = std::jthread([&]{
                while(run){
                    {
                        std::unique_lock lock(mtx);
                        cnd_var.wait(lock, [&] { return !run; });
                        if(!run) { return; }
                    }
                    Search();
                }
            });
        }
        
       void Search();

        int id;
        bool run;
        std::jthread thread;
        std::condition_variable cnd_var;
        std::mutex mtx;
}

我正在尝试像这样构造它们。

        std::vector<SearchThread> search_threads;
        for (int t_id = 0; thread_id < num_threads; t_id++) {
            search_threads.emplace_back(t_id);
        }

我得到的错误是 no matching function for call to 'construct_at'。我认为问题出在 std::mutexstd::conditional_variable 上。我可以将互斥量和条件变量声明为指针,然后在 class 构造函数中的堆上构造它们,但是这对我来说似乎很难看。

我想我的问题是,为什么不允许我这样做,有没有解决办法?

std::mutex 不可复制。它的复制构造函数被删除。 “复制互斥锁”没有逻辑意义。如果互斥量被锁定,那意味着什么? copy-constructed mutex 是不是也被锁了?如果有,是谁锁的?谁可以解锁它?

这使得 SearchThread class 也不可复制,并且有一个删除的复制构造函数。由于其成员之一是不可复制的 std::mutex,这几乎也对 SearchThread 的复制能力提出了质疑。

std::vector 要求其内容可复制。 std::vector 引以为豪的成就之一是它会在向量增长时根据需要自动复制向量中的值。这要求其内容是可复制的。 SearchThread 不可复制。您不能将其放入向量中。无论您尝试如何表达它,emplace_back 或其他方式都没有关系。 reserve()帮不了你。 std::vector 必须包含可复制的 class,没有解决方法。

您的选择是:

  1. 为您的 SearchThread 提供一个用户定义的复制构造函数,实现从 SearchThread 的另一个实例复制构造 SearchThread 的任何意义].也许复制它的所有其他成员就足够了,只需要复制构造的 SearchThread 默认构造它的互斥量。您还必须提供用户定义的赋值运算符。或者实现用户定义的移动构造函数和赋值运算符。底线是:以某种方式让你的 SearchThread copyable/movable/assignable.

  2. 使用其他一些不需要可复制对象的容器,例如 std::list