2
votes

I'm using GUIDE to create GUI in Matlab. When user hits "Start" button in GUI it starts optimisation task in background that runs in endless loop. Every iteration it outputs some information to GUI.

When I press that start button and then close GUI window Matlab freezes. When I run GUI but do not press "start" button and just close GUI it does not freeze.

How can I avoid freezing ?

5
I'd say, don't hit "Start" button...but joking aside, I'm sure you could receive further help showing what's executed on the callback function of your "Start" button or within that optimisation task. Consider placing some breakpoints within these two functions for debugging - Drodbar
It might be a good idea to use a document sharing site (like dropbox) if there's too much code to paste and have this all still be readable. I'd have no issues if you emailed it to me at the address I have in my profile. - Ben A.
@BenA. I'll update my question soon. I'll try to simplify my code to minimum code necessary to illustrate the issue and past the simplified code here. - Rasto

5 Answers

2
votes

The infinite loop that you've started isn't allowing any further events (i.e. the window close event) to be processed. You need to allow the interrupt mechanism to occur - although the 'interruptible' property defaults to 'on', you have to satisfy another requirement:

If the Interruptible property of the object whose callback is executing is on, the callback can be interrupted. However, it is interrupted only when it, or a function it triggers, calls drawnow, figure, getframe, pause, or waitfor. Before performing their defined tasks, these functions process any events in the event queue, including any waiting callbacks. If the executing callback, or a function it triggers, calls none of these functions, it cannot be interrupted regardless of the value of its object's Interruptible property.

Since you have a loop, you can insert a pause or drawnow command to allow MATLAB to process other events, such as mouse clicks on other buttons (pause(0) may work - haven't tested - to allow checking for interrupt events without actually causing the loop to slow if there are no interrupts).

(Side note: ctrl-c breaks out of loops, so you could always do that but... not ideal.)

2
votes

I have also discovered that GUI can become unresponsive because of memory fragmentation in matlab when run endlessly after say 100K iterations i deallocated all unnecessary and temporary variables and saved the result to .mat file after that instructed the gui to force quit and opened a new copy from autohotkey and loaded all previous variables from previous.mat files The GUI now works for endless cycles

1
votes

As noted by tmpearce in his answer in order for function (callback) to be interrupted it have to contain call to drawnow, figure, getframe, pause, or waitfor. And property interruptible has to be set to on on the button GUI component.

So I put pause inside the infinite (endless) cycle. However it did not work well: pause(0.0000000000000001) did slow down progress significantly (I did measure it so it isn't subjective). pause(0) did not slow down the cycle and allowed for GUI to update but did not allow to execute any other callbacks after another button was pressed.

I ended up using drawnow; command inside the cycle. It did not significantly slow down the cycle (less then 5% slow down) and the GUI works as expected.

0
votes

I learnt that just using matlabpool beforehand will keep your gui responsive. Basically it will automatically put your calculation in a worker thread.

Unfortunately can't find the reference now. But maybe you are willing to try black magic ;)

0
votes

matlab guis have lots of objects. when you close the GUI, the objects go away.

Sometimes, threads will remain after the window closes and your program keeps running.

To close this thread, I use an axis imbedded in my gui, and I make sure it still exists every loop.

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