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

如何从C++ POCO Task获取返回数据?私有std::vector数据丢失问题

问题:POCO Task执行后成员变量数据失效

我在使用C++ POCO库的Task类时遇到一个问题——runTask()执行完毕后,动态分配的内存变量似乎被释放了。比如示例里的私有成员_series,在runTask()完成后会变成空,导致getSeries()无法返回有效数据。

#include <Poco/Task.h>
#include <Poco/TaskManager.h>
#include <iostream>
#include <vector>

class FibonacciTask: public Poco::Task
{
public:
    FibonacciTask(int n): Task("FibonacciTask"), _n(n) {}

    void runTask()
    {
        long long a = 0, b = 1;
        _series.push_back(a);
        _series.push_back(b);

        for (int i = 2; i <= _n; i++) {
            long long temp = a + b;
            a = b;
            b = temp;
            _series.push_back(b);

            if (isCancelled()) {
                std::cout << "\nTask cancelled." << std::endl;
                break;
            }
        }
    }

    const std::vector<long long>& getSeries() const { return _series; }

private:
    int _n;
    std::vector<long long> _series;
};

我尝试用私有std::vector变量加getter方法访问,但无法正常工作,以下是运行异常的输出:

> g++ -I/usr/local/include/Poco -o prog main.cpp -L/usr/local/lib -lPocoFoundation

> ./prog

0 1 1 2 3 5 8 13 21 34 55

0 139993720817872 1 2 3 5 8 13 21 34 55

0 139993720817872 1 2 3 5 8 13 21 34 55

测试用的完整代码:

#include <Poco/Task.h>
#include <Poco/TaskManager.h>
#include <iostream>
#include <vector>

#include <unistd.h>

class FibonacciTask: public Poco::Task
{
public:
    FibonacciTask(int n): Task("FibonacciTask"), _n(n) {}

    void runTask()
    {
        long long a = 0, b = 1;
        _series.push_back(a);
        _series.push_back(b);

        for (int i = 2; i <= _n; i++) {
            long long temp = a + b;
            a = b;
            b = temp;
            _series.push_back(b);

            if (isCancelled()) {
                std::cout << "\nTask cancelled." << std::endl;
                break;
            }
        }
         for (const auto& num : _series) {
          std::cout << num << " ";
         }
         std::cout << std::endl;
    }

  void printSeries(){
     for (const auto& num : _series) {
       std::cout << num << " ";
     }
     std::cout << std::endl;

  }

private:
    int _n;
    std::vector<long long> _series;
};

int main()
{
   Poco::TaskManager tm;
   FibonacciTask *ft = new FibonacciTask(10);
   tm.start(ft);

   usleep(1000) ;

   ft->printSeries() ;

   usleep(1000) ;

   tm.joinAll();

   usleep(1000) ;

   ft->printSeries() ;

   usleep(1000) ;

   return 0;
}

问题原因

核心问题是POCO的TaskManager默认会在任务完成后自动删除Task对象。你在main里用new创建了FibonacciTask并传给tm.start(ft),但TaskManager在任务结束后会销毁这个Task实例,所以后续通过ft指针访问printSeries()时,已经是访问一个被释放的对象,属于未定义行为,才会出现乱码数据。

解决方法

方案一:禁止TaskManager自动删除Task对象

在调用start之前,调用tm.setAutoDelete(ft, false),这样TaskManager就不会自动销毁Task实例,你可以在后续手动管理内存(最后记得delete ft)。修改后的main函数:

int main()
{
   Poco::TaskManager tm;
   FibonacciTask *ft = new FibonacciTask(10);
   tm.setAutoDelete(ft, false); // 禁止自动删除
   tm.start(ft);

   usleep(1000) ;

   ft->printSeries() ;

   usleep(1000) ;

   tm.joinAll();

   usleep(1000) ;

   ft->printSeries() ;

   usleep(1000) ;

   delete ft; // 手动释放内存
   return 0;
}

方案二:通过回调获取结果(推荐)

如果希望TaskManager托管Task的生命周期,可以在Task类中添加回调函数,在runTask结束时将结果传递给外部,避免直接访问已被销毁的对象:

#include <Poco/Task.h>
#include <Poco/TaskManager.h>
#include <iostream>
#include <vector>
#include <functional>

class FibonacciTask: public Poco::Task
{
public:
    // 定义回调类型,用于传递结果
    using ResultCallback = std::function<void(const std::vector<long long>&)>;

    FibonacciTask(int n, ResultCallback cb): Task("FibonacciTask"), _n(n), _cb(cb) {}

    void runTask()
    {
        long long a = 0, b = 1;
        _series.push_back(a);
        _series.push_back(b);

        for (int i = 2; i <= _n; i++) {
            long long temp = a + b;
            a = b;
            b = temp;
            _series.push_back(b);

            if (isCancelled()) {
                std::cout << "\nTask cancelled." << std::endl;
                break;
            }
        }
        
        // 任务完成时调用回调,传递结果
        if (_cb) {
            _cb(_series);
        }
        
        for (const auto& num : _series) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }

private:
    int _n;
    std::vector<long long> _series;
    ResultCallback _cb;
};

int main()
{
   Poco::TaskManager tm;
   std::vector<long long> taskResult;
   
   // 定义回调函数,保存任务结果
   auto resultCallback = [&taskResult](const std::vector<long long>& series) {
       taskResult = series;
   };
   
   tm.start(new FibonacciTask(10, resultCallback));
   tm.joinAll();

   // 直接使用保存的结果
   std::cout << "最终结果:";
   for (const auto& num : taskResult) {
       std::cout << num << " ";
   }
   std::cout << std::endl;

   return 0;
}

内容的提问来源于stack exchange,提问作者Joolsy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:07:18