I've looked through the documentation, etc, but I'm not seeing anything obvious. I'd like to have a signal handler that can intercept ^C, ^\, or some other keypress that could be used to interrupt a long-running script (each discrete computation is typically <1s) and allow it to exit gracefully and save current state.
Matlab does have event handlers for COM, but it's windows-only and I'm in a *nix environment.
If the answer is 'tough luck', I'm cool with that ... I'm just not seeing anything that says I'm SOL yet.
MATLAB already interprets ^C as an interrupt. You can use onCleanup objects to ensure that your program state is preserved correctly. I.e. something like:
function testFcn
x = onCleanup( #() disp('perform cleanup here...') );
for ii=1:1000, disp(ii), pause(1), end
Run the above and hit ^C when you get bored. Obviously, you can hook any function handle in to your onCleanup object. See also the reference page for onCleanup.
Related
I'd like to have a block in simulink that serves as a tcp server. Ideally the simulation would block when it hits this block, wait until data was transfered to it by the client, and than pass that data out to be used in that step of the simulation. I'd also like the connection to persist across function calls, if possible.
I got this to work in Matlab pretty easily, using the myConnectionObject=tcpip(.) and fread(..) functions. So I figured I could just initialize the connection in the workspace, wrap my freads() into a MATLAB function block in Simulink and I'd be on my way.
However, I'm having trouble getting the tcpip connection object into the function to be visible in Simulink so I can use it with fread(). Passing it through a "From Workspace" block gives an "Unsupported input format..." error.
Thanks,
The Matlab Function block is great for quick simple mathematical functions, but when it comes to initialization or some cleanup at the end of a simulation, a
s function is the right tool. With Start and Terminate you got your places to setup and close down the server within the block.
For the use case of being able to abort parallel simulations with a MATLAB GUI, I would like to stop all scheduled simulations after the user pressed the Stop button.
All simulations are submitted at once using the parsim command, hence something like a callback to my GUI variables (App Designer) would be the most preferable solution.
Approaches I have considered but were not exactly providing a desirable solution:
The Simulation Manager provides the functionality to close simulations using its own interface. If I only had the code its Stop button executes...
parsim uses the Simulink.SimulationInput class as input to run simulations, allowing to modify the preSimFcn at the beginning of each simulation. I have not found a way to "skip" the simulation at its initialization phase apart from intentionally throwing an error so far.
Thank you for your help!
Update 1: Using the preSimFcn to set the the termination time equal to the start time drastically reduces simulation time. But since the first step still is computed there has to be a better solution.
simin = simin.setModelParameter('StopTime',get_param(mdl,'StartTime'))
Update 2: Intentionally throwing an error executing the preSimFcn, for example by setting it to
simin = simin.setModelParameter('SimulationCommand','stop')
provides the shortest termination times for me so far. Though, it requires catching and identifying the error in the ErrorMessageof the Simulink.SimulationOutput object. As this is exactly the "ugly" implementation I wanted to avoid, the issue is still active.
If you are using 17b or later, parsim provides an option to 'RunInBackground'. It returns an array of Future objects.
F = parsim(in, 'RunInBackground', 'on')
Please note that is only available for parallel simulations. The Simulink.Simulation.Future object F provides a cancel method which will terminate the simulation. You can use the fetchOutputs methods to fetch the output from the simulation.
F.cancel();
Is there a way to know when an MATLAB exits? I wanted to do some work, for example, release some resource, print some logs... I could add some code at some class's destructors. But since we cannot determine the order that MATLAB calls destructors, I am not sure which one is the last one so I can release the resource.
Can we register any callback to the MATLAB exit event if there exists such an event...?
There is no exit event I know of that's thrown when exiting from a function or MATLAB itself. However, there are two things you can do to handle final cleanup:
Use onCleanUp objects: When exiting from a function, variables in the local workspace are destroyed (and exiting from MATLAB itself will destroy objects in the base workspace). When working with resources (files, etc.), good practice is to create an onCleanUp object to handle those resources in an exception-safe manner. This is discussed in more detail in the documentation and this question: How do you handle resources in MATLAB in an exception safe manner? (like “try … finally”)
Create a finish.m file: When quitting MATLAB, it will look on the search path for a file named finish.m and run that code before terminating.
You can place any cleanup actions in the finish.m file.
Similar to startup.m, MATLAB executes this file (when found on the MATLAB search path) just prior to program termination.
Also worth looking into is onCleanup. This simple class creates an object that, when destroyed, runs the function registered during object creation. This is extremely useful when dealing with files for example:
fid = fopen(filename, 'r');
OC = onCleanup(#() any(fopen('all')==fid) && fclose(fid));
% ...file reading and processing here
% ERROR HAPPENS HERE!
% ... more processing here
fclose(fid);
meaning, the file handle fid is still closed, even though the normal fclose(fid) was not reached. This is because the object OC was cleared implicitly by MATLAB after the error.
I'm concerned about data corruption while executing a Storable::store operation. I'm writing about 100 MB to an NFS to backup my calculations at particular checkpoints but the process isn't exactly speedy.
To try to prevent corruption, I have a SIG{INT} signal handler. Right before Storable::store is called, a global variable is set indicating it isn't safe to terminate. As soon as Storable::store completes, that global variable is returned to a value to indicate it's okay to interrupt.
That global variable is used to indicate whether or not the signal handler will call die or whether it will just print a statement saying "Can't stop yet."
But am I really helping thing? I see now from reading perlipc that interrupting IO is sometimes done safely, and sometimes it is not... That is, should my signal handler end up being called in the middle of my Storeable::store operation, such a brief diversion to my signal handler subroutine may still be enough to screw things up.
Does anyone know how Storable performs in such a situation? Or is my signal handling setup actually appropriate?
Since 5.8.1, Perl uses "safe signals" (by default). When you setup a signal handler through %SIG, Perl actually installs a simple signal handler that does nothing but increment a counter. In between Perl ops, Perl checks if the counter is non-zero, and calls your signal handler if it is. That way, your signal handlers don't execute in the middle of a system call or library call.
There are only two things you need to worry about:
Modifying global vars (e.g. $!) in your signal handler.
System calls returning EINTR or EAGAIN because a signal came in during the call.
If you're really concerned that SIGINT could break store, try adding SA_RESTART to your signal handler. On Linux, this will force the system calls to be automatically retried upon a signal. This will probably defer your signal handler indefinitely since SIGINT will not be able to break out of the I/O operation. However, it should enable safe operation of Storable::store under any interruption circumstance.
Is it possible in matlab to call a function when the program I'm running is idle? I don't want this to be a parallel process. Also, I would prefer a solution where I could pause and resume the function when the main program has to run again. Kind of like an interrupt in embedded systems, in my case the main program is the interrupt.
how would I do this?
you could use a timer object to start / stop the second function. see the matlab documentation. See also this mathworks blog entry.