1
votes

I have a script that calls certain matlab programs or perl scripts to run at certain times using commands such as:

MATLAB

system('matlab', '-nosplash', '-nodisplay', '-nodesktop', '-wait', '-logfile', "$workDir/$job_name.log",  '-r', "$job_args;exit");

PERL

system("perl $jobDir/$job_args > $workDir/$job_name.out 2> $workDir/$job_name.err");

I then have some code encapsulating the above commands (each run in different scripts) which uses an alarm to kill the script if it runs for more than 2 hours or fails to run/an error occurs.

The problem is that the killing a running matlab process appears to be very difficult. If an m-file hits an error it will just hang there, never finishing or passing to 'exit'. The 2 hour limit is still reached, but it just continues. Die does not seem to kill the actual matlab script.

Is there some way, from the Perl script, to kill the running matlab script after 2 hours or if an error occurs during its execution?

An example of the code surrounding the script looks like this:

eval{
        local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
        alarm 7200;   # 2 hour timeout
        my $test = system('matlab', '-nosplash', '-nodisplay', '-nodesktop', '-wait', '-logfile', "$workDir/$job_name.log",  '-r', "$job_args;exit");
        #Run matlab with nosplash screen or matlab instance. -wait forces the script to pause until the matlab program completes. Logfile is writte to NAME.log, after prog completes, matlab closes.
        if ($test != 0) {
        die "Failed to run";
        print "$job_name failed: $?>>8";
        exec("perl", "$scriptDir/msched_result.pl", "$job_name", "FAILED", "$start_time");      #print argsfile output to .out and error to .err.
        }
        alarm 0;
        };
        if ($@) {
            die unless $@ eq "alarm\n";   # Propagate unexpected errors
            exec("perl", "$scriptDir/msched_result.pl", "$job_name", "TIMED OUT", "$start_time")
        } else {
            exec("perl", "$scriptDir/msched_result.pl", "$job_name", "DONE", "$start_time");    #run msched_result
        }

Thanks

1
I haven't matlab installed now, but if i remember good, the matlab command is an big bash script, what calls the matlab-binary. You can check what is done in the shell script, (maybe it does some special signal handling or such)... Or alternatively, you can check the sources of Math::Matlab::Local for some ideas...jm666
Look up IPC::Open2 - allows you to open an exec pipe to a process, and retain the pid (for killing if necessary)Sobrique

1 Answers

0
votes

If anyone has a similar problem to me, a solution to killing a matlab file with an error is to pre-emptively anticipate it by calling the file in a certain way.

Instead of my first example:

system('matlab', '-nosplash', '-nodisplay', '-nodesktop', '-wait', '-logfile', "$workDir/$job_name.log",  '-r', "$job_args;exit");

Try

system('matlab', '-nosplash', '-nodisplay', '-nodesktop', '-wait', '-logfile', "$workDir/$job_name.log",  '-r', "try,$job_args,catch,exit(1),end,exit(0)");

So no matter if there is an error or not when running the argument, matlab will close, returning 1 or 0 depending on whether an error occurred or not.

Alternatively

`taskkill /F /IM matlab.exe 2>&1`;

Will kill all instances of matlab, but this is pretty brute force.