"JoeW" <te********@gmail.comwrote in message
news:11**********************@p77g2000hsh.googlegr oups.com...
Now before I go into detail I just want to say that this is purely for
my own benefit and has no real world usage. I remember way back when
the tool for *nix systems called forkbomb was created. I recently
explained it to a friend of mine and at that time decided to see if I
could replicate it in C#. I have created an application that, to me at
least, mimics what fork would/should do on *nix/bsd systems. I know
that fork spawns a new process, basically identical to the parent
process. For C# this was rather easy, at least getting a new process
started. What I have is this.
while (rc >= 0)
{
rc = fork();
if (rc == 0) break;
}
static int fork()
{
int pid = Process.GetCurrentProcess().Id;
int val = 0;
try
{
Console.WriteLine("Pid {0}", pid);
string fileName =
Process.GetCurrentProcess().MainModule.FileName.Re place(".vshost",
"");
ProcessStartInfo info = new ProcessStartInfo(fileName);
info.UseShellExecute = false;
Process processChild = Process.Start(info);
val = 1;
}
catch
{
val = 0;
}
return val;
}
Now when I run this, all hell breaks loose and my system will get to
around 1000 processes in roughly 20 seconds and then crash. Is this
essentially what fork() would do in the above mentioned environments?
Or what would be a better solution to this?
Thanks in advance
Joe
Actually your system won't get at 1000 processes running, the system reserves a process
control structure but doesn't actually load and initializes that process before
Process.Start returns. So, the PID's you see don't reflect the running process,
The reason for the chaotic behavior is the result of a lack of resources, Windows cannot
create that many processes especially not that many "CLR" processes.
Each CLR process start with 3 threads , each having has a default stack of 1MB (committed),
add to that ~5MB of non shared memory for the program (CLR version dependant), so you easily
end up with a minimum of ~8MB Virtual memory per process.
Now, say that you have 2GB of RAM with a total of 4GB of VM available, that means that the
system starts thrashing even before 250 processes get created, and becomes highly
unresponsive.
When the system reaches it's max. VM size occupation, "hell breaks loose". The OS will try
to keep control, but it can no longer create processes, worse, it can no longer "initialize"
the already created processes, instead it starts recovery actions, displaying dialogs with
all kind of failure messages , possibly initiating DrWatson(s) (yet another process), which
will now require more resource like window handles and non-pageable pool memory for the USER
objects for the dialogs, but as I said your system has become highly unresponsive, you can
hardly act upon the dialog requests, and even if you can click a button and as such free a
resource, the system will automatically reassign the resource with another one, finally you
end with a system that has so many user requests pending that the system itself has
exhausted it's non pageable pool and the USER objects, you get the "false" impression that
the system crashed, but it has not (at least not on XP and higher).
If you can manage to respond to all pending request, it should be possible bring the system
back to a state where you can kill the running processes and finally get back to a normal
state.
Note that above is true for 64 bit system as well, at some time you will hit a wall, or the
RAM limit, the VM limit, the non-pageable pool and USER object resource limit and possibly
another one. Even with 8GB RAM and 12GB VM space, I wasn't able to create 1000 processes (on
W2K3 64bit) using the sample you posted, although, I was able to recover.
Willy.