将使用packaged_task的 Lambda 任务放入队列中

emplace lambda task that used packaged_task into a queue

提问人:lior 提问时间:2/20/2023 最后编辑:wohlstadlior 更新时间:2/20/2023 访问量:81

问:

所以我有一个线程池的排队实现

     template <typename F, typename... Args>
        auto enqueue(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
            using return_type = decltype(f(args...));
            auto task = std::make_shared<std::packaged_task<return_type()>>(
                    std::bind(std::forward<F>(f), std::forward<Args>(args)...)
            );
            auto result = task->get_future();
            {
                std::unique_lock<std::mutex> lock(m_queue_mutex);
                if (m_stop)
                    throw std::runtime_error("enqueue on stopped ThreadPool");
                m_tasks.emplace([task]() { (*task)(); });
            }
            m_condition.notify_one();
            return result;
        }

到目前为止一切顺利,但我想避免使用内存分配,而不是使用make_shared。

所以我把它改成这样:

template <typename F, typename... Args>
    auto enqueue(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
        using return_type = decltype(f(args...));
        auto task = std::packaged_task<return_type()>(
                std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
        auto result = task.get_future();
        {
            std::unique_lock<std::mutex> lock(m_queue_mutex);
            if (m_stop)
                throw std::runtime_error("enqueue on stopped ThreadPool");
            m_tasks.emplace([task = std::move(task)]() mutable { task(); });
        }
        m_condition.notify_one();
        return result;
    }

据我所知,这里没有副本。 任务应移入 lambda,lambda 应移至队列中,但我仍然收到此错误:

使用已删除的函数 'std::p ackaged_task<_Res(_ArgTypes ...)>::p ackaged_task(const std::p ackaged_task<_Res(_ArgTypes ...)>&) [_Res = void; _ArgTypes = {}]' 38 |
m_tasks.emplace(任务可变 { task();

我的理解是,我正在尝试复制packaged_task并且删除了它的复制构造函数。

在这里,您可以玩完整代码

https://godbolt.org/z/bEsPfabz6

谢谢!

C++ 复制构造函数

评论

3赞 user17732522 2/20/2023
您没有在问题中显示错误的原因。这是因为它的类型是. 仅适用于可复制的可调用对象。m_tasksstd::queue<std::function<void()>>std::function

答: 暂无答案