0

我正在尝试扩展一些人在这里帮助我的内容Call function inside a lambda pass to a thread所以我的工作类可以支持 move 构造函数和 move operator=,但我的问题是我的类是this通过复制(或引用)绑定的) 到线程,以便它可以访问类值。其中有几个atomic<bool>,一个condition_variable和一个mutex

但是当我尝试移动它时,因为线程绑定到另一个条件变量mutexatomics,我对它所做的任何事情都不起作用。我怎样才能解决这个问题?我是否需要使用更复杂的对象并移动它而不是 lambda,以便线程可以引用它?还是有其他选择。一如既往的帮助将不胜感激:)。

这是实现的片段(MWE)。

class worker {
public:
    template <class Fn, class... Args>
    explicit worker(Fn func, Args... args) {
        t = std::thread(
            [&func, this](Args... cargs) -> void {
                std::unique_lock<std::mutex> lock(mtx);
                while (true) {
                    cond.wait(lock, [&]() -> bool { return ready; });

                    if (terminate)
                        break;

                    func(cargs...);

                    ready = false;
                }
            },
            std::move(args)...);
    }

    worker(worker &&w) : t(std::move(w.t)) { /* here there is trouble  */ }

    worker &operator=(worker &&w) {
        t = std::move(w.t);
        terminate.store(wt.terminate);
        ready.store(wt.ready);
        return *this; 
        /* here too */
    }

    ~worker() {
        terminate = true;
        if (t.joinable()) {
            run_once();
            t.join();
        }
    }

    worker() {}

    void run_once() {
        std::unique_lock<std::mutex> lock(mtx);
        ready = true;
        cond.notify_one();
    }

bool done() { return !ready; }

private:
    std::thread t;
    std::atomic<bool> ready, terminate; // What can I do with all these?
    std::mutex mtx;                     //
    std::condition_variable cond;       //
};

int main() {
    worker t;
    t = worker([]() -> void { cout << "Woof" << endl; });
    t.run_once();
    while(!t.done()) ;
    return 0;
}

对不起,代码的大转储。

4

1 回答 1

2

我会通过说它worker是不可复制和不可移动来“修复”它,并将它留给用户worker来存储它,unique_ptr就像他们想要移动它一样。这一点都没有错。其实很普通

如果你绝对希望这个类是可移动的,你可以使用 Pimpl 设计模式:创建Worker::Impl一个workerunique_ptr. 该类Impl将是不可复制和不可移动的,并且基本上是您当前的worker类。lambda 将有一个指向Impl类的指针,而不是worker类。除了转发到类函数的and 函数之外,worker该类将不包含任何内容,并且默认的复制和移动 ctors/操作符对于这两个类都将正常工作(worker 将是可复制的但不可移动,impl 将是不可复制和不可移动的)。unique_ptrImplImpl

于 2016-07-27T17:41:38.800 回答