使用 parfeval() 时的 Matlab-GUI 警告:"Unable to save App Designer app object."



我正试图通过按下启动按钮来调用Matlab GUI中的并行函数。

一开始,我试图调用一个函数("ReadTwinCAT"(,但总是收到以下错误消息:

"警告:无法保存App Designer应用程序对象。不支持保存用于matlab.apps.AppBase对象。">

因为我以为我已经在GUI中使用了这样的并行函数,所以我不知道我做错了什么。。。

Matlab应用程序设计器代码:

properties (Access = private)
running_state = 0; % Description
tcClient;
db_conn;
end
methods (Access = private)
function ReadTwinCAT(app)
while app.running_state == 1
disp('running')
pause(0.1) 
end  
disp('stopped')
end         
end

% Callbacks that handle component events
methods (Access = private)
function StartButtonPushed(app, event)
app.running_state = 1;
pool = gcp(); %Initialize pool of workers
parfeval(pool, @ReadTwinCAT, 0, app); %Call parallel function
end
end

好吧,我想我从Mathworks的工作人员那里找到了答案:https://www.mathworks.com/matlabcentral/answers/366576-will-there-be-a-support-of-the-parallel-toolbox-in-matlab-app-designer#comment_720548

注意访问parfor循环内的应用程序对象或通过并行计算工具箱调用的任何其他函数的限制。

如果您需要访问应用程序的属性,请直接将其作为值传递,例如,而不是

b = [0,0];  
parfor i=1:2
b(i) = app.myprop*2
end

使用

tmp = app.myprop;
b = [0,0];  
parfor i=1:2
b(i) = tmp*2
end

因此,您似乎无法在并行函数中访问(或设置(app对象的属性。如果你想获取数据,你可能需要使用parallel.pool.DataQueue建立一个通信系统。你的例子很难并行化。更好的选择可能是在running_state属性中添加一个侦听器,和/或使用timer函数。

这样做的主要缺点是,您从计时器调用的函数实际上并不是并行的——它在同一个线程中运行,所以如果您在ReadTwinCAT中有大量计算,我认为它会导致GUI中的滞后/无响应。

我已经修改了你的代码,使用计时器而不是parfeval:

properties (Access = private)
running_state = 0; % Description
runningTimer;
tcClient;
db_conn;
end
methods (Access = private)
function ReadTwinCAT(app, varargin)
if app.running_state == 1
disp('running')
else
stop(app.runningTimer);
disp('stopped')
end
end
end
% Callbacks that handle component events
methods (Access = private)
function StartButtonPushed(app, event)
app.running_state = 1;
app.runningTimer = timer;
app.runningTimer.Period = 0.1;
app.runningTimer.ExecutionMode = 'fixedRate';
app.runningTimer.TimerFcn = @app.ReadTwinCAT;
start(app.runningTimer)
end
end

相关内容

最新更新