Matlab GUI中的无限循环导致关闭GUI时Matlab冻结?

Posted

技术标签:

【中文标题】Matlab GUI中的无限循环导致关闭GUI时Matlab冻结?【英文标题】:Endless cycle in Matlab GUI causes Matlab to freeze when GUI is closed? 【发布时间】:2012-07-17 23:15:27 【问题描述】:

我正在使用 GUIDE 在 Matlab 中创建 GUI。当用户点击 GUI 中的“开始”按钮时,它会在后台启动以无限循环运行的优化任务。每次迭代它都会向 GUI 输出一些信息。

当我按下那个开始按钮然后关闭 GUI 窗口时,Matlab 冻结。当我运行 GUI 但不按“开始”按钮并关闭 GUI 时,它不会冻结。

如何避免冻结?

【问题讨论】:

我会说,不要点击“开始”按钮......但开玩笑的,我相信你可以得到进一步的帮助来展示你的“开始”按钮的回调函数上执行了什么或在该优化任务中。考虑在这两个函数中放置一些断点进行调试 如果要粘贴的代码太多并且仍然可以阅读,那么使用文档共享站点(如 Dropbox)可能是个好主意。如果您通过我在个人资料中的地址通过电子邮件将其发送给我,我不会有任何问题。 @BenA。我会尽快更新我的问题。我将尝试将我的代码简化为说明问题所需的最少代码,并在此处省略简化代码。 【参考方案1】:

您开始的无限循环不允许处理任何进一步的事件(即窗口关闭事件)。您需要允许interrupt 机制发生 - 尽管'interruptible' 属性默认为'on',但您必须满足另一个要求:

如果正在执行其回调的对象的 Interruptible 属性 开启,回调可以被中断。然而,它被打断了 只有当它或它触发的函数调用drawow,figure, getframe、暂停或等待。在执行他们定义的任务之前, 这些函数处理事件队列中的任何事件,包括任何 等待回调。如果正在执行的回调,或者它的一个函数 触发,不调用这些函数,不能被中断 无论其对象的 Interruptible 属性的值如何。

由于您有一个循环,您可以插入 pausedrawnow 命令以允许 MATLAB 处理其他事件,例如鼠标单击其他按钮(pause(0) 可能有效 - 尚未测试 - 允许如果没有中断,则检查中断事件而不会真正导致循环变慢)。

(旁注:ctrl-c 会跳出循环,所以你总是可以这样做,但……并不理想。)

【讨论】:

谢谢,很好的回答。我已经使用像“pause(0.0001)”这样的暂停进行绑定,它可以工作,但会显着减慢优化周期...使用“pause(0)”不会减慢进度并允许 GUI 更新,但它不会阻止当我关闭我的 GUI 窗口时,整个 Matlab 不会冻结。您有什么建议如何不减慢进度,而是防止关闭窗口后冻结?感谢您的任何想法 补充说明:如果主 Matlab 窗口变得无响应,我不能到 ctrl-c - 这正是我关闭我的 GUI 窗口时会发生的情况...... 一旦 GUI 响应,您可以设置 closeRequestFcn 回调以跳出循环。这是我对您需要做什么的最佳猜测。 2) 是的,我关于 ctrl-c 的注释是指在关闭窗口之前执行它,而不是在 matlab 停止响应之后。【参考方案2】:

我还发现,当 matlab 无休止地运行时,由于内存碎片,GUI 可能会变得无响应 在说 100K 次迭代后,我释放了所有不必要的临时变量并将结果保存到 .mat 文件 之后指示gui强制退出 并从 autohotkey 打开一个新副本并从 previous.mat 文件加载所有以前的变量 GUI 现在可以无限循环工作

【讨论】:

【参考方案3】:

正如tmpearce 在his answer 中所指出的,为了中断函数(回调),它必须包含对drawow、figure、getframe、pause 或waitfor 的调用。并且属性 interruptible 必须在按钮 GUI 组件上设置为 on

所以我在无限(无尽)循环中设置了暂停。但是效果不佳:pause(0.0000000000000001) 确实显着减慢了进度(我确实对其进行了测量,因此它不是主观的)。 pause(0) 没有减慢循环并允许 GUI 更新但不允许在按下另一个按钮后执行任何其他回调。

我最终在循环中使用了drawnow; 命令。它并没有显着减慢周期(减慢不到 5%),并且 GUI 按预期工作。

【讨论】:

【参考方案4】:

我了解到,事先使用matlabpool 将使您的 gui 保持响应。基本上它会自动将您的计算放入工作线程中。

很遗憾,现在找不到参考资料。但也许你愿意尝试黑魔法 ;)

【讨论】:

【参考方案5】:

matlab guis 有很多对象。当您关闭 GUI 时,对象就会消失。

有时,线程会在窗口关闭后保留,您的程序会继续运行。

为了关闭这个线程,我使用嵌入在我的 gui 中的轴,并确保它在每个循环中仍然存在。

h=gca;
for x = 1:WIDTH:(size(image,1)-WIDTH-OVERLAP-1)
    for y = 1:HEIGHT:(size(image,2)-HEIGHT-OVERLAP-1)
        %if the main gui closes, then the axis will change...
        %in that case, you should stop this thread.
        if(h == gca)
            window = image(x:x+WIDTH+OVERLAP,y:y+HEIGHT+OVERLAP);%%account for a 10 pixel overlap
            imshow(window)
            pause(.01);  
        else
            close all;
            return;
        end


    end
end

【讨论】:

以上是关于Matlab GUI中的无限循环导致关闭GUI时Matlab冻结?的主要内容,如果未能解决你的问题,请参考以下文章

matlab中的GUI,轴中的图像循环

怎么Matlab美化gui界面

急急急!!!matlab gui界面设计

使用后台并行无限循环 C# 读取缓冲区 [关闭]

matlab设计GUI

怎样用matlab编写双缝干涉的GUI界面