Thread: Forks v's threads

  1. #1
    Registered User
    Join Date
    Dec 2001
    Posts
    40

    Forks v's threads

    I have a program that uses fork to generate a number of child processes. Without going into too much detail it generates 19 child processes that go off and do their thing and exit when they have finished.
    There is a wait statement (below), but it does not seem to be working as the original programmer intended as it leaves behind a number of zombies and the sysadmins are complaining (even thought its not really a problem because the zombies do all die when the parent process terminates so it doesnt actually fill the process table and they have never had to reboot the box due to this problem in the 12 years that the program has been running)

    the wait line is

    Code:
    waitid(P_ALL,0,&infop,WNOHANG);
    Now I have been reading up on this and my understanding of the waitis statement is:
    the P_ALL says wait for a change in state of any of the children spawned by the parent. My understanding of the WNOHANG bit is to tell it not to wait.
    Unfortunately most of the examples I have found use only one parent and child so the wait is fairly simple for that.
    I think the programmer assumed that each of the child processes will have terminated by this stage, and this is where I think the problem is. It only looks for a change in state of one of its child processes, not for all of them, and I assume because it does not test each child process for termination, they sit around waiting for their turn to pass their return code which never happens until the program terminates.
    So would one solution be if I were to put the waitid into a loop build on an array of child process ids and test each id in turn?

    How about if I rewrite the fork bit to use threads, would that be a cleaner solution?

  2. #2
    Super Moderator Harbinger's Avatar
    Join Date
    Nov 2004
    Posts
    74
    You need to wait() for each child to exit - so if you fork() 10 times, then you need to wait() 10 times as well.

    If you don't know how many children you have forked, then perhaps there is some status for wait() which means 'no more children'

  3. #3
    Registered User
    Join Date
    Apr 2005
    Posts
    28
    Quote Originally Posted by Harbinger
    You need to wait() for each child to exit - so if you fork() 10 times, then you need to wait() 10 times as well.

    If you don't know how many children you have forked, then perhaps there is some status for wait() which means 'no more children'
    Not really. wait() will wait until one process exits and will clean all the zombie ones. However, the WNOHANG means that it will not hang the program to this statement. This is done by that if there is no process terminating (ie zombie) it will return something (NULL I think).

    If you want to learn more on this read the correspoding chapter on processes (ch3 if i recall correctly) on the advanced linux programming. Google for the book. If i recall well in the wait family there are four waits. Read the section or man wait3 wait4...

  4. #4
    Super Moderator Harbinger's Avatar
    Join Date
    Nov 2004
    Posts
    74
    >wait() will wait until one process exits and will clean all the zombie ones.
    Where does http://www.hmug.org/man/2/wait.php mention anything about a single call waiting for ALL zombie processes in one call?

  5. #5
    Registered User
    Join Date
    Apr 2005
    Posts
    28
    Quote Originally Posted by Harbinger
    >wait() will wait until one process exits and will clean all the zombie ones.
    Where does http://www.hmug.org/man/2/wait.php mention anything about a single call waiting for ALL zombie processes in one call?
    Absolutely nowhere. In fact it does not even wait a zombie process, it returns and frees the resources used by the children process. Furthermore, it waits as long as one/any process is terminated. What I said comes from a program of mine where I periodically call wait to clean up the zombie processes, can't remember though if it cleans all of them or only one at a time... A simple program with a few forks could show the truth I guess. Anyway, the main point is to call wait periodically to clean zombie processess as the WNOHANG will return if there is no child to be waited for... The following looks more than the man page I was referring to:
    http://www.hmug.org/man/2/wait.php
    Cheers and apologies if I made a mistake...

  6. #6
    Registered User
    Join Date
    Dec 2001
    Posts
    40
    Thanks all.
    In pseudocode I have:

    for 0 to maxchildren
    fork child
    Do stuff
    increment counter

    followed by

    for 0 to maxchildren
    wait
    increment counter

    And that seems to work, each wait handles one child process. Which is how I interpret the man page harbinger posted.

  7. #7
    Registered User
    Join Date
    Apr 2005
    Posts
    28
    Good... but then you do not use WNOHANG anymore and subsequently you suspend the execution of the parent program until any single child process terminates (or with the for loop, until all children terminate)... which in my case is a luxury I cannot afford.

    PS: And by the way the question was how many zombie processes wait clears. There is no "difference of opinion" on that it is satisfied/returns with only one process terminating, except from wait4 which waits a particular process.
    Last edited by odysseus.lost; 11-11-2005 at 05:46 AM.

  8. #8
    Registered User
    Join Date
    Dec 2001
    Posts
    40
    Quote Originally Posted by odysseus.lost
    how many zombie processes wait clears.

    Sorry that is what I meant by 'handles'. I assume that each terminating child process goes into a queue that is controlled by the OS, and wait takes the next one off the queue when it is called (if there is one there, otherwise it waits until one is put into the queue), and accepts the return code from the child which allows it to complete cleanly.

    The alternative I thought of but its is a bit over the top for what I need because my parent process does as you say have the luxury of being able to wait for the children to finish would be:

    Create a structure to store the child process id and a status flag
    Declare an array of these structures

    When a child process is forked, store the process id in the array and set the status flag as on or true or running

    Then call waitid periodically with the options P_ALL and WNOHANG, so it will check for any waiting children, but not hang around if there is nothing there. When a terminating child is detected the waitid receives the process id of the child back again, which you can then reset the status flag in the array for that process id to off or false or ended. Then at least you can keep track of what has started and what has ended.

    And if an array is not suitable, maybe a linked list of the process id's that you can remove nodes from when the child process has finished.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 10-17-2008, 11:28 AM
  2. Yet another n00b in pthreads ...
    By dimis in forum C++ Programming
    Replies: 14
    Last Post: 04-07-2008, 12:43 AM
  3. Classes and Threads
    By Halloko in forum Windows Programming
    Replies: 9
    Last Post: 10-23-2005, 05:27 AM
  4. problem with win32 threads
    By pdmarshall in forum C++ Programming
    Replies: 6
    Last Post: 07-29-2004, 02:39 PM
  5. Block and wake up certain threads
    By Spark in forum C Programming
    Replies: 9
    Last Post: 06-01-2002, 03:39 AM