You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreadPool实现中~__nat()已删除错误的排查咨询

线程池实现中的clang编译错误分析(~__nat()已删除)

我正在实现一个线程池,clang编译器抛出了无法理解的~__nat()已删除错误。这个线程池包含1个负责规划并向队列添加任务的Scheduler线程、1个负责从队列取出任务并分配子线程的Executor线程,以及每个任务对应的子线程,问题出在Executor模块:

struct Executor {
    std::shared_ptr<SharedData> data_ptr_;

    // constructor
    explicit Executor (std::shared_ptr<SharedData>& data_ptr):
      data_ptr_ (data_ptr)
    {}


    // methods
    void execute () {
      while (true) {
        auto cur_task = data_ptr_->queue_.Take();
        if (cur_task == std::nullopt) break;
        std::thread child_thread {&Executor::executeChild, this, std::move(cur_task)};
        // ...
      }

      // join child threads here
    }

    void executeChild (Task task) {
      // ...
      task();
      // ...
    }

  }; 

编译器对std::thread child_thread {&Executor::executeChild, this, std::move(cur_task)};这行代码报错,错误信息如下:

In template: attempt to use a deleted function error occurred here in instantiation of function template specialization 'std::__thread_execute<std::unique_ptr<std::__thread_struct>, void (tp::Executor::*)(fu2::detail::function<fu2::detail::config<true, false, fu2::capacity_default>, fu2::detail::proper... in instantiation of function template specialization 'std::__thread_proxy<std::tuple<std::unique_ptr<std::__thread_struct>, void (tp::Executor::*)(fu2::detail::function<fu2::detail::config<true, false, fu2::capacity_default>, fu2::detai... in instantiation of function template specialization 'std::thread::thread<void (tp::Executor::*)(fu2::detail::function<fu2::detail::config<true, false, fu2::capacity_default>, fu2::detail::property<true, false, void ()>>), tp::Executor ... '~__nat' has been explicitly marked deleted here

错误原因与解决方法

  • 报错本质:~__nat()已删除是clang底层模板实例化失败的间接报错,核心问题是std::thread构造时无法正确处理你传递的参数组合,不是__nat本身的问题,而是上层参数传递触发了模板内部的删除函数调用。

  • 代码错误点:

    1. 参数类型不匹配:cur_task是std::optional<Task>,但executeChild的参数是Task。虽然你判断了cur_task不为空,但std::thread在构造时会尝试将参数打包到内部存储,std::optional的移动操作无法直接适配成员函数的Task参数要求,导致模板实例化失败,触发了底层的删除函数错误。
    2. 子线程生命周期隐患:当前代码中创建的child_thread是局部变量,循环迭代结束后会被销毁,此时线程若未join或detach会直接终止程序,这是后续运行时的问题,但当前编译错误的直接原因是参数传递。
  • 解决步骤:

    1. 先解包std::optional获取Task对象:
      修改线程构造代码,把std::move(cur_task)改成std::move(*cur_task),确保传递的是Task类型而非std::optional<Task>:
      auto cur_task = data_ptr_->queue_.Take();
      if (cur_task == std::nullopt) break;
      std::thread child_thread {&Executor::executeChild, this, std::move(*cur_task)};
      
    2. 存储子线程并统一join:
      把创建的子线程存入容器,避免局部变量销毁导致的线程终止,在循环结束后统一等待所有子线程完成:
      void execute () {
        std::vector<std::thread> child_threads;
        while (true) {
          auto cur_task = data_ptr_->queue_.Take();
          if (cur_task == std::nullopt) break;
          child_threads.emplace_back(&Executor::executeChild, this, std::move(*cur_task));
        }
      
        // join child threads here
        for (auto& t : child_threads) {
          if (t.joinable()) {
            t.join();
          }
        }
      }
      
    3. 确保Executor对象生命周期:如果Executor本身不是被shared_ptr管理,子线程运行时this指针可能失效,建议将Executor用std::shared_ptr持有,或者把executeChild改为静态函数,传递std::shared_ptr<SharedData>和Task,避免依赖this指针。

内容的提问来源于stack exchange,提问作者Amir Mokhammed-Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:24:09