Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

as i just fork-bombed my router with a botched attempt to speed up a quick hack, i thought i'd take this opportunity to offer some wisdom on safe handling of fork() for those without the scars of personal experience. *grin*

if you aren't familiar with the concept, in a nutshell, fork-bombs are class of 'rabbit' processes (they suck up pools of pids, not just one) that have no cap on the number of of pids they syphon, or commonly have a cap far in excess of the size of the number of pids existing/possible in the system -- the modern cancer approach, grow as much and as fast as possible, and do it in a multi-threaded way.

if you have made acquaintence with fork-bombs in the past, you can ingore this, and stick to your line: "been there, done that, bought the t-shirt".


The Problem:

> is there anything that I can do to fix it?

pull the plug. the pid-space is full, nothing on the system can spawn new processes for _anything_ owning to system being all forked up. (sorry) that includes spawning processes for new connections, spawing new shells, su, shutdown, halt, etc.

there is a kernel module you can install to prevent fork-bombs, if it isn't already too late to do that. if you have privs to install kernel modules that is...


The Cause

while( ){ fork(); }

this and all isomorphisms, including loops with conditions, and loops with fork() in a conditional block, (if the condition in question is incorrect in a manner that always evaluates as true) are fork-bombs if the loop runs more than about a dozen times.


Technical Explanation

one codes fork() as:

if( fork() ){ # code } else { # code }

and this evaluates as both true AND false (one in the old process, one in the new, respectively). the kicker is, both processes continue normally after the end of the if() block, (with whatever differences they acquired in the course of the block).

that means a loop written:

while( ){ if( fork() ){ # code else{ # code } }

will run twice on the first pass, four times on the second, eight on the third, etc. producing a cheap way to test binary permutations, and a very easy way to use 1048576 threads in just 20 iterations.

this, it should be noted, is not a valid approach to programming anything short of a quantum computer. (for which, i understand, it is the only method. -- go fig.)


The Solution

fork() should never be used in a loop, except as follows:

while( ){ if( fork() ){ # code } else { # code exit; # <--- !!!! } }

which will produce exaclty one thread running the loop, and one additional thread per iteration, thus totalling only 21 threads for 20 iterations in contrast with the above.

for what it's worth, this is easiest for me to remember simplified as

"if fork, else exit"

of course, isomorphisms of the above will work, so this will also fine:

while( ){ unless( fork() ){ #code exit; } }

you may notice i only ever put the exit; in the false portion of the conditional, this may not matter to everyone, but technically fork() returns true for the parent and false for the child, and i'm in favor of orderly process management. *grin*

-- Xanatax.


"i'd like to see a positive LSD story, would that be newsworthy? just once? hear what it's all about? 'Today a young man on acid realized that all matter is merely energy condensed to a slow vibration, that we are all one consciousness experiencing itself subjectively, there no such things as death, life is only a dream and we are the imagination of ourselves. Here's Tom with the weather...'"
  --Bill Hicks


In reply to fork-bomb! by Xanatax

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-04-19 13:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found