Re: [Bulk] Re: fork and exec

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2008-05-24 at 15:39 -0400, Greg Freemyer wrote:
[....]
> I also think it is useful to realize that UNIX was basically designed
> for systems that have a MMU even though low-end systems in the late
> 70s / early 80s did not have them.

The first ones (also before) didn't have a MMU and the first versions of
"Unix" ran on it.

> I believe there were implementations that ran on 286 based hardware
> without MMUs way back then, but they were very kludgy and definately
> not the design target for UNIX.

Of course they were as that was common hardware in the 60s and
(earlier?) 70s.

> With an MMU even if a multi-megabyte app is forked, a majority  the
> memory pages are initially shared between the parent and child.  A

That came later - first via a separate vfork() Sys-Call - also on
non-MMU systems - which didn't copy anything and meant to be used if you
execv() afterwards anyways. Copy-on-write was implemented later on
MMU-systems (and fork() and vfork() were more or less "merged" as there
was no real need to separate it).

> copy on write system is used to create individual RAM pages if either
> the parent or the child writes to a specific shared RAM page.
> 
> Thus the fork call is very efficient and effectively does the minimum
> amount of work necessary to create a new process from a parent
> process.  Therefore if exec is immediately called by the child, little
> wasted effort was caused by it being two discrete steps as opposed to
> one larger step.

ACK - in that area is that the somewhat optimal situation.
But I don't think that Kernighan and Ritchie had that goal in their
initial design in the 60s;-)

> And as someone else said with current implementations you have a lot
> of control of exactly what is carried over from parent to child via
> the clone call and thus can optimize the process.

Conceptually fork() and execve() are two totally different (and
independent) operations:
- fork() simply creates a new process. And the simplest implementation
  just lets that function return twice - once in the original - "parent"
  - process and one in the new - "child" - process with different return
  values.
- execve() loads the code of a another (or the same) process and starts
  at the main() function. Yes, it actually starts before somewhere else
  but for normal programmer it starts usually at the main() function.

Of course you can argue that "start another program" could be combined
in one Sys-Call but that won't kill the need of the 2 above Sys-Calls as
you need it for other actions like "restart the same daemon on top of
the old" (after a configuration change or after a change of the binary)
or simply the "I want a separate process for this sub-task in my
application".

The latter could be done with threads but that implies a thread lib (and
not all systems - especially small ones - have or want one) and you
don't have some kind of "snapshot" feature on the memory as the
sub-thread could change data in the main thread (or so need
synchronization with all potential problems like "deadlock").

Or think of a shell with a piped commandline (as in
`ls -als | grep '.c$' | wc -l` for a simple example. Yes, that could be
done more simple with "grep -c", etc.). The shell has actually to do
something specific in the child processes after the fork() and before
the execve().
As a simple exercise: Write a "startbinary()" function (somewhat similar
to system(3), popen(3) is of no help here) simply combining fork() and
exec() and implement with that function a piped commandlines (and use it
with more than one pipe).
Run that under `strace` and compare the output with the same commandline
under `strace sh -c` (and it could be more efficient - using less
sys-calls - than the typical "sh -c").

And the performance loss of 2 sys-calls instead of one on starting
another program is IMHO not really measurable - not even if you have
everything in a RAM disk, hot caches, etc.

	Bernd
-- 
Firmix Software GmbH                   http://www.firmix.at/
mobil: +43 664 4416156                 fax: +43 1 7890849-55
          Embedded Linux Development and Services


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux