Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Kill a serial of jobs with a button click in Perl/TK

by GotToBTru (Prior)
on May 22, 2015 at 16:30 UTC ( [id://1127482]=note: print w/replies, xml ) Need Help??


in reply to Kill a serial of jobs with a button click in Perl/TK

Docs for Tk::ExecuteCommand suggest the kill_command is a method of the same object that execute_command. We can't see the connection (if any) between $run_job1_bttn and $ec_job1, for instance. We need more to work with, if you want more specific help.

Dum Spiro Spero
  • Comment on Re: Kill a serial of jobs with a button click in Perl/TK

Replies are listed 'Best First'.
Re^2: Kill a serial of jobs with a button click in Perl/TK
by Janish (Sexton) on May 25, 2015 at 01:41 UTC

    Every run job button IE: $run_job1_bttn will trigger a subroutine to execute a child script. The subroutine RunAll works just fine as it is able to trigger each jobs running sequentially but the problem is on the KillAll subroutine, it seem fail to kill all jobs (triggered by the RunAll sub) but only manage to kill the first one.

      kill, AFAIK, only works on running processes. If they are executing sequentially, only one of them is "running", the rest is ... waiting? queued? (what I want to say is: they probably are not "processes" yet)

      So you have to remove them from the queue (or whatever), preferrably before killing the first, in order to avoid race conditions.

        kill, AFAIK, only works on running processes.

        If you think of the kill(2) system call, this is wrong. You can send signals to all processes, not only those that are currently running. (That limitation would make signals quite useless on all single-core systems, where only one process can be running at any point of time. You could only send signals to the own process.)

        If they are executing sequentially, only one of them is "running", the rest is ... waiting? queued?

        Tk::ExecuteCommand creates "background" processes, i.e. the processes are started and execute_command() returns before the process just started terminates. If you issue several execute_command() calls (for different instances of Tk::ExecuteCommand), you create several processes, running in parallel.

        Update: I'm not quite sure about the previous paragraph. execute_command() calls several Tk methods that allow Tk to continue working, but execute_command() returns only after it considers the command to have finished ($self->{'-finish'} changes). Tk continues to handle events, so by clicking another button, another execute_command() may run.

        (what I want to say is: they probably are not "processes" yet)

        This is an instance of Tk::ExecuteCommand where either execute_command() has not yet been called or the executed child process has already terminated. There seems to be no method that can be used to test if the process is still running, unfortunately. The documentation does not detail what happens when a process terminates or when the methods get_status() and kill_command() are called before execute_command().

        Looking at the source code gives some hints:

        • get_status() returns undef if there is not status yet, but this is undocumented and may change.
        • execute_command uses $self->{'-finish'} to wait for the process to exit (using waitVariable()). Testing that value from the outside would tell you if a process is currently running. Of course, this is undocumented and I would consider this a bad practice, as $self->{'-finish'} is private.
        • kill_command() not only kills the executed command, but also all of its child processes, using killfam() from Proc::Killfam Again, this is not documented and may change.
        • kill_command() actually does not kill the executed command, and it also does not kill the child processes. It just sends a SIGTERM signals. Any process can catch or ignore SIGTERM. The code seems to assume that the executed command and the child processes terminate very soon after receiving the SIGTERM signal, as it removes the readable fileevent handler before even sending the signal. No attempt is made to kill processes that do not exit after receiving SIGTERM. Again, nothing of this is documented, the behavoiur may change. It seems that the author mixed up SIGTERM and SIGKILL, or simply forgot that processes may catch or ignore SIGTERM.
        • The PID of the executed command is available in $self->{'-pid'}, it starts as undef and is set as soon as the command is started, but cleared only before starting a new command. So you can not rely on that PID, because the operating system may reuse the PID. Guess what: This is undocumented and may change. And you should not mess with object internals.
        • The command to be executed is a string. (That's also undocumented. I expected an array. Or at least I hoped for an array.) To this string, " 2>&1 |" is appended before passing it to a two-argument open. This means that you have to mess with the shell, that you have to follow quoting rules for a shell that may be different on every system, and of course, the two-argument form of open has its own set of problems. Also, STDOUT and STDERR of the command will be mixed into a mess of bytes. Nothing of this can be read in the documentation. It seems that the author ignored, did not read, or did not understand Safe Pipe Opens. That would allow to avoid all problems of the shell and of a two-argument open.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1127482]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2024-04-18 23:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found