in reply to break thread with system(...) call

Without threads:

## Start the program asynchronously my $pid = system 1, "padprog.exe"; ## Wait for some period sleep $timeout; ## If program is still running, kill it kill 1, $pid if kill 0, $pid;

Be aware that if your command contains shell meta characters, then the pid will be for cmd.exe, not whatever exectuable it starts, and killing the shell won't normally kill the other process


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: break thread with system(...) call
by aaaone (Initiate) on Jul 16, 2008 at 19:19 UTC
    great! it seems to be the most progressive... I see, you understand the problem as for complex scripts and so cmd.exe ... but I think that it will be some kind of process tree for windows, I'm right?
    perl->cmd.exe->prog.exe

    maybe there is a way to follow the process tree or kill cmd.exe in such a way that all children will be also killed? Thaanks)
      maybe there is a way to follow the process tree or kill cmd.exe in such a way that all children will be also killed?

      Yes. Use Win32::CreateProcess and the include CREATE_NEW_PROCESS_GROUP. Use it to start cmd.exe and then supply your complex command line.

      When you kill cmd.exe, any child processes it has created will be killed also.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Some further info on this:

        1. You must use perl's built in kill, with a signal number 21 (SIGBREAK).

          Win32::Process::Kill() only gets the immediate child, not the group.

        2. Only processes that share the same console will be killed.

          That means that if all the processes in your complex commands are simple command line apps, then all children and their grandchildren etc. will be killed as a group.

          But if any of the processes allocate their own console, or do not use a console (eg. notepad.exe), then they will survive. I do not have a simple solution for these.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        Thanks a lot! I've thought so much and determined to do like this (taskkill.exe) is windows native program (I've recently read about it.. yes, also at perlmonks.org)):
        my $pid = system (1, 'FOR /R C:\ %G IN (*.*) DO type %G'); sleep(2); print `taskkill.exe /PID $pid /T /F`;
        To detect the state of process, I use this:
        #return (kill 0,$pid); - don't know but it doesn't work.. my $throbj; if (Win32::Process::Open($throbj,$pid,0)) { my $ecode; $throbj->GetExitCode ($ecode); if ($ecode==Win32::Process::STILL_ACTIVE) { return 1; } #STILL ACTIVE return 0; }
        I'm a bit sad that I've read too late about Win32::Job and Proc-Background but my resulting solution seems to work well...

        Guys, thanks once again! ) you helped me very very.