in reply to Testing whether a process has finished

I can not use waitpid, because this would suspend my program until the process is finished.

You should read the docs again. It's not necessarily so.

From the description of the kill function, I thought that sending signal 0 to the process would tell me, whether it is still running:

That's not what the docs say. It tests whether the process still exists, not whether it's running.

But this always returns true, even though I can see that the process has already finished long time ago. What am I doing wrong?

I explained this to you yesterday! Is there something you didn't understand?

Update: Added second para

  • Comment on Re: Testing whether a process has finished

Replies are listed 'Best First'.
Re^2: Testing whether a process has finished
by ELISHEVA (Prior) on Sep 10, 2009 at 15:39 UTC

    Those docs are just a bit confusing and I can see why rovf is concerned that waitpid would suspend his program.

    First, the docs say that non-blocking wait is only available for "machines supporting either the waitpid(2) or wait4(2) system calls". Perhaps rovf's machine is one of the machines that doesn't?

    Second, it isn't entirely clear how one would write a program to use a non-blocking wait, assuming there is one. The docs give an example of a while loop but the ellipsis in the example are placed above the loop, not within the loop. I'm guessing that one is expected to use a polling pattern, but if that were to be non-blocking, one would have to place one's application code inside the polling loop rather than above it. To avoid suspending your program I'm guessing the code should look something like this?

    use POSIX ":sys_wait_h"; #... do { # ... do some stuff while waiting ... # check in to see if the process has ended ... $kid = waitpid(-1, WNOHANG); } while $kid > 0;

    Best, beth

      Perhaps rovf's machine is one of the machines that doesn't?

      He has Windows, and it works for Windows too.

      >perl -MPOSIX=:sys_wait_h -le"my $pid = system 1, $^X=>(-e=>'sleep 5') +; while (waitpid($pid, WNOHANG) == 0) { print 'waiting'; sleep 1; } p +rint 'done'" waiting waiting waiting waiting waiting waiting done

      To avoid suspending your program I'm guessing the code should look something like this?

      use POSIX qw( WNOHANG ); # Returns false if alive. # Returns true if dead. (Reaps and sets $?) # Throws expection on error. (Sets $!) sub is_child_dead { my ($pid) = @_; my $rv = waitpid($pid, WNOHANG); die("waitpid: $!\n") if $rv == -1; return $rv; }
        Thanks a lot! Now after seen your solution (which, of course, works), I also understand the docs for waitpid better....

        -- 
        Ronald Fischer <ynnor@mm.st>
      Perhaps rovf's machine is one of the machines that doesn't?
      It's Windows 2000, but the code is also supposed to run on Windows XP.
      Second, it isn't entirely clear how one would write a program to use a non-blocking wait, assuming there is one.
      Indeed I see from the perldocs only that waitpid accepts flags, but there is no description of what the possible value of these flags might be...

      -- 
      Ronald Fischer <ynnor@mm.st>

        but there is no description of what the possible value of these flags might be...

        From the docs (emphasis mine),

        If you say "$kid = waitpid(-1, WNOHANG);", then you can do a non-blocking wait

Re^2: Testing whether a process has finished
by rovf (Priest) on Sep 11, 2009 at 09:28 UTC
    I explained this to you yesterday! Is there something you didn't understand?
    It seems so. I understood from your explanation (which was about killing a process), that after sending the kill signal, the process still resides in the process table and I can't expect that it disappears immediately. So far no problems.

    Here we have a different situation, in that it is not about killing a process: I am going to implement a busy wait for a process to end by itself. When the process finishes, I understand that Windows might still take some time to remove the process from the process table, after it is ended - maybe a few seconds, but certainly not minutes, isn't it? So I thought that sooner or later, after sending a kill 0, the process must have disappeared and kill should return 0 (indicating that "it reaches zero processes").

    Maybe I really misunderstood what you explained to me yesterday - could you please point out where my understanding is wrong?

    -- 
    Ronald Fischer <ynnor@mm.st>

      maybe a few seconds, but certainly not minutes, isn't it?

      The process will continue to exist in zombie state until all handles to it are closed. That includes the one the parent has in order to collect the child's exit code.

      That particular handle is closed when you call wait/waitpid. If you don't call wait/waitpid for minutes after the child stopped running, the process is going to be a zombie for minutes.