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

MATLAB中如何实现可容忍异步进程取消的同步结果返回?

解决MATLAB异步计算被取消后同步调用无法获取结果的问题

问题背景

我们有一个高开销的可扩展计算进程,部署在交互式MATLAB环境中,新数据随时可能生成。规则是:新数据到达时,若当前计算正在运行,立即终止它,基于所有现有数据重新启动计算,确保尽早拿到最新全量数据的结果。但触发初始计算的同步函数需要在最终完成的计算结束后拿到结果——哪怕它最初触发的异步进程被后续新数据取消了。

原示例代码的问题:当同步调用result = h.AddData(n).fetchOutputs;后,如果中途点击按钮添加新数据,最初返回的Future会被取消,同步调用直接报错,虽然最终包含n的结果会存入对象,但无法传递给同步进程。

解决方案1:基于Future职责传递的链式等待

核心思路是:每次取消旧Future时,让同步调用绑定的等待逻辑自动转向新启动的Future。给类新增一个跟踪「最终需要等待的Future」的属性,同步调用等待这个属性对应的Future,而非单次AddData返回的临时Future。

修改后的类代码:

classdef ExampleClass < handle
    properties
        InputData
        OutputData
    end

    properties (Hidden, Transient)
        WorkFuture parallel.Future
        % 新增:跟踪当前最新的、需同步等待的完成态Future
        LatestCompletionFuture parallel.Future
    end
    
    methods
        function obj = ExampleClass()
            uibutton(uifigure, ButtonPushedFcn = @(~,evt) obj.AddData(evt.Source.Parent.CurrentPoint(1)));
            % 初始化一个已完成的Future,避免首次调用出错
            obj.LatestCompletionFuture = parfeval(@() true, 1);
            obj.LatestCompletionFuture.wait();
        end

        function output = DoWork(obj)
            pause(2);
            drawnow
            output = obj.InputData * 2;
        end

        function val = StoreOutput(obj,val)
            obj.OutputData = val;
            % 更新LatestCompletionFuture为携带当前结果的完成态Future
            obj.LatestCompletionFuture = parfeval(@() val, 1);
        end

        function F = AddData(obj,val)
            % 取消未完成的当前计算
            if ~isempty(obj.WorkFuture) && ~obj.WorkFuture.isDone()
                obj.WorkFuture.cancel();
            end
            obj.InputData(end+1) = val;
            % 启动新异步计算,完成后更新输出和跟踪Future
            obj.WorkFuture = parfeval(parallel.Pool.empty,@obj.DoWork,1);
            obj.WorkFuture.afterAll(@obj.StoreOutput,1);
            F = obj.WorkFuture;
        end

        % 新增同步获取最终结果的方法
        function result = SyncAddAndGetResult(obj, val)
            obj.AddData(val);
            % 等待最新的完成态Future,自动适配后续触发的新计算
            obj.LatestCompletionFuture.wait();
            result = obj.LatestCompletionFuture.fetchOutputs{1};
        end
    end
end

使用方式:直接调用同步方法即可,无需额外处理取消逻辑:

h = ExampleClass;
% 同步添加数据并等待最终结果,中途点击按钮不影响返回值
result = h.SyncAddAndGetResult(10);

解决方案2:基于事件通知的等待机制

核心思路是:当计算完成并更新OutputData时,触发自定义事件,同步调用等待该事件触发后读取结果。

修改后的类代码:

classdef ExampleClass < handle
    properties
        InputData
        OutputData
    end

    properties (Hidden, Transient)
        WorkFuture parallel.Future
    end

    % 定义计算完成的自定义事件
    events
        CalculationCompleted
    end
    
    methods
        function obj = ExampleClass()
            uibutton(uifigure, ButtonPushedFcn = @(~,evt) obj.AddData(evt.Source.Parent.CurrentPoint(1)));
        end

        function output = DoWork(obj)
            pause(2);
            drawnow
            output = obj.InputData * 2;
        end

        function val = StoreOutput(obj,val)
            obj.OutputData = val;
            % 计算完成后触发事件
            notify(obj, 'CalculationCompleted');
        end

        function F = AddData(obj,val)
            if ~isempty(obj.WorkFuture) && ~obj.WorkFuture.isDone()
                obj.WorkFuture.cancel();
            end
            obj.InputData(end+1) = val;
            obj.WorkFuture = parfeval(parallel.Pool.empty,@obj.DoWork,1).afterAll(@obj.StoreOutput,1);
            F = obj.WorkFuture;
        end

        % 同步获取结果的方法
        function result = SyncAddAndGetResult(obj, val)
            obj.AddData(val);
            % 创建监听器并等待事件触发
            listener = addlistener(obj, 'CalculationCompleted', @(~,~) true);
            wait(listener);
            delete(listener);
            result = obj.OutputData;
        end
    end
end

使用方式:和方案1一致,直接调用同步方法即可:

h = ExampleClass;
result = h.SyncAddAndGetResult(10);

方案说明

  • 两种方案均能实现:同步调用触发计算后,即使初始异步进程被后续操作取消,仍能等待最终完成的计算并获取结果。
  • 方案1基于MATLAB并行计算的原生Future逻辑,适合熟悉并行工具链的场景;方案2基于事件通知,逻辑更直观,适合对事件机制更熟悉的开发者。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:25:31