[comp.unix.questions] Need help spawning a child

brian@apt.UUCP (Brian Litzinger) (06/21/89)

I have a daemon process that spawns child processes to do some
sub-tasks.  The sub-tasks are asynchronise and the parent doesn't
care how successful the children are.  Therefore the parent process
never waits for the child.  This results in my process table filling
up with <defunct> processes over time.  

I simply want the child processes to exit and go away forever.  I
do not want the parent to have to wait on it.

I use fork(2) to create the process, and have used both exec(2), and
system(3) to run the actual job.  I've tried setpgrp(2) in the child
process but it did not make any difference.

From ps(1):

   "A process that has exited and has a parent, but has not yet been
    waited for by the parent, is marked <defunct>."

Elsewhere I found information that a defunct process holds no
system resources except to a slot in the process table.

I have a V.3.2 system, so BSDism's won't help me.

Any help would be appreciated.

<>  Brian Litzinger @ APT Technology Inc., San Jose, CA
<>  UUCP:  {apple,sun,pyramid}!daver!apt!brian    brian@apt.UUCP
<>  VOICE: 408 370 9077      FAX: 408 370 9291

dune@cbnewsl.ATT.COM (Greg Pasquariello) (06/21/89)

In article <1661@apt.UUCP> brian@apt.UUCP (Brian Litzinger) writes:
>I have a daemon process that spawns child processes to do some
>sub-tasks.  The sub-tasks are asynchronise and the parent doesn't
>care how successful the children are.  Therefore the parent process
>never waits for the child.  This results in my process table filling
>up with <defunct> processes over time.  
>
>I simply want the child processes to exit and go away forever.  I
>do not want the parent to have to wait on it.
>
><>  Brian Litzinger @ APT Technology Inc., San Jose, CA
                                                                      
                                                                         
                                                                   
Simply use signal() to ingnore the death of a child.  In SVR3.2 this will
have the desired effect of letting the child die without creating
zombies.
                                                                         
                                                                         
                                                                                 
                                                                      
Regardless of what my mail path says, I am really Greg Pasquariello
at ...!att!picuxa!gpasq
                                                                        
                                                                          

jik@athena.mit.edu (Jonathan I. Kamens) (06/22/89)

In article <873@cbnewsl.ATT.COM> dune@cbnewsl.ATT.COM (Greg
Pasquariello) writes:

>Simply use signal() to ingnore the death of a child.  In SVR3.2 this will
>have the desired effect of letting the child die without creating
>zombies.

I can't speak for SVR3.2, but I can tell you for sure that this will
not work under BSD (in fact, I just checked with a five line program).
The method I use under BSD to accomplish this is a bit more
convoluted, but it just *might* be a bit more portable (I'm not sure,
because I've done very little work under anything other than BSD and
the SysV machine I have an account on is down right now :-).

Under BSD, you set up a signal handler which responds to SIGCHLD by
calling wait(0).  The return value of the wait() call is irrelevant --
it serves only to tell the kernel that it can free up the resources
reserved for the zombie child.

#include <signal.h>

main()
{
   ...
   signal(SIGCHLD, handler);
   ...
}

handler()
{
   wait(0);
}

Jonathan Kamens			              USnail:
MIT Project Athena				432 S. Rose Blvd.
jik@Athena.MIT.EDU				Akron, OH  44320
Office: 617-253-4261			      Home: 216-869-6432

dune@cbnewsl.ATT.COM (Greg Pasquariello) (06/22/89)

In article <12131@bloom-beacon.MIT.EDU> jik@athena.mit.edu (Jonathan I. Kamens) writes:
>In article <873@cbnewsl.ATT.COM> dune@cbnewsl.ATT.COM (Greg
>Pasquariello) writes:
>
>>Simply use signal() to ingnore the death of a child.  In SVR3.2 this will
>>have the desired effect of letting the child die without creating
>>zombies.
>
>I can't speak for SVR3.2, but I can tell you for sure that this will
>not work under BSD (in fact, I just checked with a five line program).
>
>Jonathan Kamens			              USnail:
                                                                 
                                                                       
What Jonathan says is correct.  The method I suggested was new to SYSV
with release 3.?.  Although the original poster asked specifically for
3.2 information, I should have stated that this method was not portable.
                                                                       
                                                                          
                                                                           
Greg Pasquariello
...!att!picuxa!gpasq
                                                                            
                                                                   

janm@eliot.UUCP (Jan Morales) (06/23/89)

In article <873@cbnewsl.ATT.COM> Greg Pasquariello writes:
>Simply use signal() to ingnore the death of a child.  In SVR3.2 this will
>have the desired effect of letting the child die without creating
>zombies.

About a year ago I moved from working primarily on System V systems to
working on BSD-derived ones.  I used to assume this was true from my
experience on System V but it appears not to be true for the SunOS 4.0.1
I work on now.  Neither "signal(SIGCLD, SIG_IGN)" nor the equivalent
sigvec() call seem to do the trick; I always get zombies that must be
waited for.  Is this true or am I missing something?

Jan
-- 
{uunet,pyramid}!pyrdc!eliot!janm

gar@cory.Berkeley.EDU (Gary D. Wong) (06/27/89)

>In article <873@cbnewsl.ATT.COM> dune@cbnewsl.ATT.COM (Greg
>Pasquariello) writes:
>
>>Simply use signal() to ingnore the death of a child.  In SVR3.2 this will
>>have the desired effect of letting the child die without creating
>>zombies.

I have a very similar problem that envolves a programs that sleeps in the
background, using the sleep call.  When one of its children die, I want it
to wake up and perform some task, and go back to sleep. So I used signal
or sigset to call a signal handling function upon receiving SIGCLD. (This
is a SYS V box).  This results in a zombie being created.

My problem is, that to prevent a zombie process, I have to ignore SIGCLD with
sigignore(SIGCLD), and my parent process does not wake up.  Is there
any other way to prevent a zombie other than by ignoring SIGCLD?

Also, does anyone know what will happen to my sleeping process after the signal
handling call? Will it go back to sleep, or continue as if it were given 
the alarm signal? What would be the effect of having the signal handler
send the alarm signal to the process?

Thanks,

 Gary D. Wong  gar@cory.berkeley.edu  //   "It is better to remain silent   \\
 University of California, Berkeley   <<    and thought a fool, than to     >> 
 (415) 642-9304		              \\    open your mouth and confirm it" //
 Disclaimer: "Please, Colonel Hogan, I see NOTHING, I see NOOOTHINNNNNG!"

jik@athena.mit.edu (Jonathan I. Kamens) (06/27/89)

In article <14972@pasteur.Berkeley.EDU> gar@cory.Berkeley.EDU.UUCP (Gary D.
Wong) writes:

>My problem is, that to prevent a zombie process, I have to ignore
>SIGCLD with sigignore(SIGCLD), and my parent process does not wake
>up.  Is there any other way to prevent a zombie other than by
>ignoring SIGCLD?

I've posted this already; you should read the whole message chain
before asking a question that has already been answered.  Using
sigignore(SIGCLD) to get rid of zombie processes is unportable, and
will only work on SysV-based systems.  The portable way to get rid of
zombie processes is to establish a signal handler for the SIGCLD
signal, and to do wait(0) in that signal handler.  The wait(0) call
cleans up exited child processes and "allows" them to exit.

>Also, does anyone know what will happen to my sleeping process after
>the signal handling call? Will it go back to sleep, or continue as if
>it were given the alarm signal? What would be the effect of having
>the signal handler send the alarm signal to the process?

If a call to sleep() is interrupted by a signal for which a signal
handler has been established, then the sleep() will resume where it
left off after the signal handler exits.  I am fairly sure this will
happen on all architectures; I just tested it on BSD, so I know it
will happen there.

Jonathan Kamens			              USnail:
MIT Project Athena				432 S. Rose Blvd.
jik@Athena.MIT.EDU				Akron, OH  44320
Office: 617-253-4261			      Home: 216-869-6432

stripes@wam.UMD.EDU (06/27/89)

In article <12244@bloom-beacon.MIT.EDU> jik@athena.mit.edu (Jonathan I. Kamens) writes:
[stuff deleted]
>>Also, does anyone know what will happen to my sleeping process after
>>the signal handling call? Will it go back to sleep, or continue as if
>>it were given the alarm signal? What would be the effect of having
>>the signal handler send the alarm signal to the process?
>
>If a call to sleep() is interrupted by a signal for which a signal
>handler has been established, then the sleep() will resume where it
>left off after the signal handler exits.  I am fairly sure this will
>happen on all architectures; I just tested it on BSD, so I know it
>will happen there.
According to Bach's "The Design of the Unix Operating System", SysV
calls that are interupted by a signal return an error, this is true
under Ultrix as well where it returns EINTER, or someting like that.
For sleep() it looks like a good idea, but for everything else even
Mr. (or is it Dr?) Bach seems to admit that BSD's restart-syscall-after-
catching-signal is nicer.
In this case a simple "for(;;) sleep()" would do, even 'tho I prefer
to use a label and a goto just to answer a Kernal Kludge with a User Kludge.
>Jonathan Kamens			              USnail:
>MIT Project Athena				432 S. Rose Blvd.
>jik@Athena.MIT.EDU				Akron, OH  44320
>Office: 617-253-4261			      Home: 216-869-6432
-- 
           stripes@wam.umd.edu          "Security for Unix is like
      Josh_Osborne@Real_World,The          Mutitasking for MS-DOS"
      "The dyslexic porgramer"                  - Kevin Lockwood
		  Looking for a termcap entry for a PC running APL*PLUS...

guy@auspex.auspex.com (Guy Harris) (06/29/89)

>What Jonathan says is correct.  The method I suggested was new to SYSV
>with release 3.?.

Huh?  If you're talking about ignoring SIGCLD, that's been in System V
since "Release 1".

uri@arnor.UUCP (Uri Blumenthal) (06/29/89)

From article <12244@bloom-beacon.MIT.EDU>, by jik@athena.mit.edu (Jonathan I. Kamens):
> 
> I've posted this already; you should read the whole message chain
> before asking a question that has already been answered. 

Jonatan, sorry, but how are you going to read the whole message chain? Or how
can I access messages, which were posted , let's say, two weeks ago? By the way,
it has a double interest to me, because then I'll be able to get hold on some
source which was posted some time ago. So - how?

Uri.

"But where is yesterday?"

"Where are the snows of yesteryear?"

dune@cbnewsl.ATT.COM (Greg Pasquariello) (06/29/89)

In article <1858@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>>What Jonathan says is correct.  The method I suggested was new to SYSV
>>with release 3.?.
>
>Huh?  If you're talking about ignoring SIGCLD, that's been in System V
>since "Release 1".

Ok, Ok, but it only cleaned up zombies correctl post 3.0

npl@cbnewsi.ATT.COM (nickolas.landsberg) (06/30/89)

The old tried and true method (before SIGCLD) and which, I think, also
worked for BSD systems, was to run the processes as "grandchildren."
Parent does a fork() and a wait();
Child Does a fork() and an exit(); (init inherits grandchild)
Grandchild executes normally.

Since the "parent" waited for it's "child," no zombie there.
Since init inherits all "orphans," and also does wait()'s, no zombie
there either.  The length of time the parent wait()'s is minimal, since
the exit() out of the child occurs almost immediately.

rogerk@mips.COM (Roger B.A. Klorese) (06/30/89)

Get a turkey baster.
-- 
ROGER B.A. KLORESE      MIPS Computer Systems, Inc.      phone: +1 408 720-2939
928 E. Arques Ave.  Sunnyvale, CA  94086             voicemail: +1 408 991-7802
{ames,decwrl,pyramid}!mips!rogerk                     rogerk@servitude.mips.COM
"I want to live where it's always Saturday."  -- Guadalcanal Diary

duncan@dg-rtp.dg.com (W. Lee Duncan) (06/30/89)

In article <1661@apt.UUCP> brian@apt.UUCP (Brian Litzinger) writes
of needing to creating asynchronous children and not having his
process table filled up.

Try orphaning your children (sounds mean, doesn't it).  Just do
something like:


void create_an_orphaned_process()
{
	int	pid1, pid2;


	if ((pid1 = fork()) < 0)
		end_all_life("no need to live");

	if (pid1 == 0) {

		/* the child -- it'll fork and die */

		if (pid2 = fork()) < 0)
			end_all_thought_of_life("why me");

		if (pid2 == 0) {
			exec("some grandchild program");
			end_all_sentient_life("shouldn't get here");
		} else
			exit(0);	/* the child is no longer needed */
	}

	return;	/* the original process goes on its merry way */

} /* end function */

>
><>  Brian Litzinger @ APT Technology Inc., San Jose, CA
><>  UUCP:  {apple,sun,pyramid}!daver!apt!brian    brian@apt.UUCP
><>  VOICE: 408 370 9077      FAX: 408 370 9291
>

--
W. Lee Duncan, Data General, RTP     - "How can you be two places at once
UUCP: {world}!mcnc!rti!dg-rtp!duncan -  when you're really no place at all?"
DOMAIN: duncan@dg-rtp.dg.com         -                Firesign Theatre