Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

I got zombies

by reptile (Monk)
on Aug 08, 2000 at 02:58 UTC ( #26694=perlquestion: print w/ replies, xml ) Need Help??
reptile has asked for the wisdom of the Perl Monks concerning the following question:

The situation: I have a process that forks, uses setsid() and then the new process forks again. One process sits and waits for connections and the other loops infinitely to do some background stuff (using shared memory, the process that takes connections will be able to fool with the data the other process uses). The problem is, when I kill the process leader -- the one that setsid()s -- its kid doesn't go away. I was under the impression that when you kill the process group leader the children are killed off too, but I guess I was wrong, or I'm doing something wrong.

The question: How can I get the children to go away when their parent is killed?

local $_ = "0A72656B636148206C72655020726568746F6E41207473754A"; while(s/..$//) { print chr(hex($&)) }

Comment on I got zombies
Download Code
Re: I got zombies
by BlaisePascal (Monk) on Aug 08, 2000 at 03:48 UTC
    It doesn't sound like zombies to me.. Zombies die before their parents, not the otherway around.

    If I understand you, you are doing something like this:

    if (!fork()) { setsid() exit if fork(); ...do child stuff } else {...do parent stuff}
    (Note: I can't find any perl documentation on setsid, where am I not looking?)

    According to Stevens (Advanced Programming in the UNIX Environment) that is basically the standard recipe for creating a detached process -- one in it's own session and process group. And since the child's real parent is dead, it was inherited by init (process 1).

    So if that is what you are doing, then you are doing exactly the wrong thing to do if you want the child to die when the parent does.

    If you want the background process to terminate when the foreground process terminates cleanly (i.e., not from "kill -9"), you could use a flag set by parent when shutting that is shared between processes, or or pass the child's PID to the parent (through shared memory) and send a signal from the exiting parent. If you wanted a SIGINT or SIGKILL to go to both processes, you could use setpgrp() to place the background process in the same process group as the parent (but you can do the same thing by not using setsid).

    Why are you using setsid() in the first place?

      Where you were not looking was the POSIX module. That is where setsid() is defined.

      EDIT
      I went and read it closely. Actually it isn't defined there. It just tells you to see your man page.

      DESCRIPTION
      setsid() creates a new session if the calling process is not a process group leader. The calling process is the leader of the new session, the process group leader of the new process group, and has no controlling tty. The pro­ cess group ID and session ID of the calling process are set to the PID of the calling process. The calling pro­ cess will be the only process in this new process group and in this new session.
      The usage in the code is absolutely identical to what my man page (Debian) has to say in its notes about this function.

      BTW I have been amazed lately at how good Google is for picking up information on random technical things. For instance here is a search on setsid.

      There is no foreground process. It's using setsid() to disassociate the child from the parent, then the parent exits. The remaining process (the child) forks a process it's the parent of and they both do their own thing.

      I should have just left out the setsid() because you're apparently confused by what I intended to do with it. I wasn't sure if it was pretinent or not, so I mentioned it.

      I'm doing something like this:

      use POSIX qw/setsid/; if ( fork() ) { exit; } else { setsid(); } # now the foreground process is gone and I'm the child if ( fork() ) { &do_something(); } else { &do_something_else(); }

      They both stay around in an infinite loop doing whatever they're supposed to do. I have to kill them both or whichever one I don't kill sticks around. Like from ps auxf:

      iniquity 26464 0.5 15.9 2976 2348 ? S 21:41 0:00 perl -w ./si +ncd.pl iniquity 26465 0.0 15.4 2920 2276 ? S 21:41 0:00 \_ perl -w +./sincd.p

      If I kill 26464, 26465 doesn't go away.

      local $_ = "0A72656B636148206C72655020726568746F6E41207473754A"; while(s/..$//) { print chr(hex($&)) }

Re: I got zombies
by tye (Cardinal) on Aug 08, 2000 at 07:35 UTC

    I vaguely recall in some versions of Unix that process groups and/or sessions implied that signals sent to the process leader got also sent to all members of the process group. However, I also vaguely recall this changing so that this was only true for a "foreground" session when the signals are generated from the controlling tty.

    So I don't think you can force this automatic signal propogation in the version of Unix that you are using. I did do some looking in the only Unix man pages I have access to, and got minor confirmation on some of this.

    So you might want to read up on setsid(2), setpgrp(2), termio(7), and/or kill(2) for the version of Unix that you are using. In Perl, you can put a minus sign in front of the signal name/number to indicate that you want to kill a process group instead of an individual process.

            - tye (but my friends call me "Tye")
Re: I got zombies
by AgentM (Curate) on Aug 08, 2000 at 20:40 UTC
    Dear Helpless Victim of UNIX confusion,
    use Threads; Love, POSIX Man
      Threaded Perl is labelled an experimental feature when you compile it for extremely good reason. Use threads only if you don't mind having a major risk of serious race conditions and random core dumps.
        Then use Pthreads in xs or skip perl altogether. perl6 is said to have some super security thread objects as well as IPC. I can imagine that will cut into runtime. perhaps threaded interpreted language is not the best way to go. But anyhow, async() works fine and one doesn't need much else (at least in perl5)
Re: I got zombies
by reptile (Monk) on Aug 09, 2000 at 04:49 UTC

    Well I just want to say thank you all for your help. To summarize, as sr. tye pointed out, signals aren't propegated through process groups, so I have to do that myself. Yuck, but ok. Now I just gotta figure out how to get a SIGINT to break from a blocking IO::Socket::INET::accept (should I use non-blocking? is that possible? I'll figure it out)

    So, thank you, especially tye.

    local $_ = "0A72656B636148206C72655020726568746F6E41207473754A"; while(s/..$//) { print chr(hex($&)) }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://26694]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2014-08-28 09:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (259 votes), past polls