Every now and then I stumble on a case where Matlab hangs, becomes totally unresponsive and requires me to kill the Matlab process externally (via the task manager). The undocumented solution is frustratingly simple (see below), and yet I keep forgetting it.
The last time this happened was only two days ago, and by pure coincidence a reader’s comment yesterday happened on the same page where I explained the problem and solution. So I am taking this opportunity to explain the problem and the workaround, before my senility takes over and I forget again… 🙂
The symptom – Matlab hangs
The symptom is easily detectable: you’re happily working on your favorite Matlab GUI application, when suddenly some modal dialog window appears – perhaps a msgbox, a questdlg or an inputdlg. After clicking the <OK> button, Matlab seems to freeze, and any attempt to close the window or to stop the GUI fails. Forget about Ctrl-C – it simply hangs.
The only workaround is to open the operating system’s task manager and kill the Matlab process.
There are several odd things here: Firstly, the task manager shows that the Matlab process is not consuming any CPU. Secondly, the hang does not appear consistently – sometimes it does, other times not, making debugging extremely difficult. Moreover, when we debug the code, stepping through the source-code lines one at a time, everything seems to behave perfectly normal; it is only when running the program in continuous mode that the hang appears.
The solution – adding drawnow
The underlying reason for the hang appears to be that when we close the modal dialog window, it is sometimes not yet fully destroyed when we proceed with our program. It is my belief that this creates race-conditions which in some cases cause a deadlock between Matlab’s Main Thread and Java’s Event Dispatch Thread (EDT). Matlab-EDT synchronization problems are often time-dependent, which explains why the hang sometimes occurs and sometimes not.
While debugging EDT synchronization problems is notoriously difficult, the solution is often extremely simple — Just add a combination of drawnow and a short pause:
uiwait(msgbox(...)); drawnow; pause(0.05); % this innocent line prevents the Matlab hanganswer = questdlg(...); drawnow; pause(0.05); % this innocent line prevents the Matlab hang switch answer ...
Adding drawnow and pause forces Matlab to flush EDT’s event queue, thereby ensuring synchronization before proceeding with the Matlab code. This is actually quite important when integrating Java GUI components in Matlab figures (especially before R2008b’s javaObjectEDT became available).
In the particular case of the Matlab dialog hang, drawnow is probably sufficient and pause is unnecessary. As noted by Bill York (MathWorks’ dev team leader who is responsible for such stuff) here, drawnow is similar but not exactly the same as pause. I often use both of them, since I discovered via trial-and-error that in the general case of EDT-related timing issues, different situations respond better to either of them, and I never remember which one to use to ensure proper rendering. So the drawnow/pause line appears very often in my code, quite possibly even in places where they are not strictly needed.
The actual needed value of the pause may vary, depending on GUI complexity and CPU power/load, but 0.05 seems to be large enough for most cases, while being small enough to be virtually unnoticeable by the user. In rare cases I needed to go as high as 0.1, but then again in some cases it is not needed at all.