我有一个脚本,运行的时间比我预期的要长得多,它已经运行了3天,只取得了55%的进展。
我很乐意在67%左右停止它(我可以没有剩下的33%),但如果我现在停止它(ctrl+c或ctlr+break),我将失去所有的数据。
那么有没有办法暂停Matlab,也许进入调试模式,这样我就可以检查变量而不丢失数据?
命令(需要在启动函数之前手动输入!)
dbstop if error
应该捕获ctrl-c并使您处于调试模式。
我假设你在这里迭代地做一些事情,而不是依赖于内置的matlab函数。
我通常解决这个问题的方法是在这个计数器上有一个迭代计数器和一个if
语句——当条件满足时,语句有一个断点。
像这样:
itCounter = 0;
itHalt = 100;
while (someCondition)
if (itCounter == itHalt)
itCounter = 0; %<= Put a breakpoint here
else
itCounter = itCounter+1;
end
% Here you calculate away whatever you need to calculate
end
这样,在每次itHalt迭代中,您都会得到一个断点。此外,由于我们正在处理matlab,您可以在击中断点后立即更改itHalt的值。
我正在考虑另一个解决方案:
让我们有一个基本上由主循环组成的脚本。
脚本周期性地将执行状态信息(例如完成的迭代次数)写入日志文件。
此外,脚本定期从输入文件
中读取一个数字。1 meaning "continue"
0 meaning "stop the script execution"
在模拟开始时,在文件中写入1。
用户可以读取日志,并可以决定在某个点停止脚本。
要做到这一点,他只需要在文件中更改1 to 0
作为保存。
if节检查在它上面读到的值。
If 1, nothing appens and the script continues running.
If 0, a break statement terminates the main loop and the script stops.
在break
语句之前,在if部分中,脚本将整个工作空间保存到.mat
文件中。
用户现在可以访问MatLab(他甚至可以关闭MatLab),并且可以查看,例如,在脚本生成的输出文件中,处理它们,制作一些绘图等等。
然后他可能决定从脚本停止的位置继续执行。
在脚本的开头,一个变量控制脚本的执行方式:
Mode 0: start from the beginning
Mode 1: resume the script
if - else
section管理用户选择。
特别是,如果选择模式1,脚本将加载先前保存的工作空间(存储在.mat文件中),然后脚本的一些变量的值被设置为旧值。
举个例子:当for循环的索引为100时,脚本停止。
如果for循环定义为
for i=start_loop_1:100000
if的Mode 1中,start_loop_1设置为i+1 (i
的值保存在.mat
文件中)。
这允许循环从它停止的点"继续"执行。
为了有效地"恢复"脚本的运行,脚本中使用的一些其他变量可能需要在Mode 1部分中以相同的方式进行管理。
在这种情况下,"大","复杂"的脚本可能是困难的,但是…不是不可能
此解决方案已在以下脚本中实现。
我可以看到一个潜在的危险,包括在不幸的情况下,用户保存包含1,0的文件,同时脚本读取它。
% Flag to select the running mode
% Mode 0: start from the beginning
% Mode 1: resume the running
continue_my_script=1;
% if "Mode 1" has been selected, the "old" workspace is loaded and some
% variables are properly set
if(continue_my_script == 1)
load my_script_data
start_loop_1=i+1;
start_loop_2=1;
% if Mode 0 has been selected some variables are set to their default value
else
start_loop_1=1;
start_loop_2=1;
% counter to enable writing of the log file
cnt_log=0;
% counter to enable reading the "go / no go" input file
cnt_go=0;
end
% Definition of the condition for writing the log file (in this case, a
% certain number of iterations")
log_iter=13;
% Definition of the condition for reading the "go / no go" input file (in
% this case, a certain number of iterations")
go_nogo_iter=20;
% Starting point of the "real script"
for i=start_loop_1:100000
% Increment the log counter
cnt_log=cnt_log+1;
% if "log_iter" have been done, update the log file
if(cnt_log == log_iter)
cnt_log=0;
t=clock;
fp=fopen('my_script_log.log','wt');
fprintf(fp,'i= %d at %d %d %fn',i,floor(t(4)),floor(t(5)),t(6));
fclose(fp);
end
% Another loop of the script
for j=start_loop_2:100000
a(i,j)=sqrt(i);
end
% Increment the "read input file" counter
cnt_go=cnt_go+1;
% if "go_nogo_iter" have been done, read the go_nogo input file
if(cnt_go == go_nogo_iter)
cnt_go=0;
fp1=fopen('my_script_go.log','rt');
go_nogo=fscanf(fp1,'%d');
fclose(fp1);
% If the user made the decision to stop the execution, save the workspace
% and exit; otherwise ... do noting, just continue running
if(go_nogo == 0)
save my_script_data
break;
end
end
end
好吧,我只是用其他评论用户的输入来重新表述我在评论中所说的话。如果你的脚本是一个MATLAB脚本,(不是一个函数),所有的变量都可以从工作区中访问,只要你没有在脚本中显式地调用"clear",如果脚本停止了。在通常情况下,ctrl+c将终止正在运行的脚本。脚本中使用的MATLAB变量仍然可以从MATLAB工作区中访问。
我不认为在代码已经运行时可以做任何事情,除非您事先放置一些钩子。其他的一些建议是有益的。这是另一个我喜欢的:假设你晚上要离开,但第二天回来,所以你想让你的代码运行14个小时,然后停下来,等待你在这段时间内得到多少数据。
start_time = now;
final_time = start_time + 10/86400; % datenums are in days in Matlab, so +14/24 for 14 hours
% alternative: final_time = datenum('12-Aug-2015 09:00:00');
while now < final_time
% do work
disp('Working...')
pause(1)
end
% potential clean up code to save results
disp('Clean up code.')