[linux-l] Java Thread vs. c fork

Ihno Krumreich ihno at lst.de
Mi Okt 22 01:00:45 CEST 2003


On Mon, Oct 20, 2003 at 04:05:25PM +0200, Jan-Benedict Glaw wrote:
> On Mon, 2003-10-20 21:43:58 +1000, Peter Ross <Peter.Ross at alumni.tu-berlin.de>
> wrote in message <20031020213910.S626 at guckloch.zuhause>:
> > On Sun, Oct 19, 2003 at 10:51:25PM +0200, Thomas Knop wrote:
> > > weil SUN behauptet unter Solaris w?rden Threads (lightwight processes)
> > > viel schneller als reinrassige Prozesse gestartet werden.
> > 
> > Vielleicht kann jemand etwas zu den "Spezialitaeten" von Linux-Threads
> > sagen, da ich immer wieder hoere, dass Linux-Threads wenig von einem
> > lightwight process haben, sondern ein nur wenig abgespeckter Prozess
> > seien?
> 
> Linux-Threads hei?t erstmal, da? Du die glibc mitbenutzt... Dann hast Du
> Dein "Hauptprogramm", einen Master Thread (der verwaltet alle weiteren)
> und eben Deine Arbeitstiere.
> 
> Threads werden via clone() angelegt. Unter Linux ist die Implementierung
> da so, da? clone() und fork() fast dasselbe tun. Einziger Unterschied:
> Bei fork werden alle Speicher-Seiten auf read-only gesetzt, soda? sie
> kopiert werden kann, wenn Vater oder Kind darauf zugreift. Wird nicht
> (schreibend) auf den Speicher zugegriffen, hast Du nahezu die
> clone()-Geschwindigkeit.

fork und clone haben den gleichen Code. Sieht wie folgt aus:
=================================================
asmlinkage int sys_fork(struct pt_regs regs)
{
        return do_fork(SIGCHLD, regs.esp, &regs, 0);
}

asmlinkage int sys_clone(struct pt_regs regs)
{
        unsigned long clone_flags;
        unsigned long newsp;

        clone_flags = regs.ebx;
        newsp = regs.ecx;
        if (!newsp)
                newsp = regs.esp;
        return do_fork(clone_flags, newsp, &regs, 0);
}
===================================================

Das ist der Code aus dem 2.4.19-Kern von SuSE. D.h. die eigentliche
Arbeit wird von do_fork erledigt.

> 
> > Unter Solaris, was ich allerdings derzeit nicht zur Verfuegung habe, sind
> > Threads wesentlich schneller generiert als Prozesse zu forken.
> 
> Das deutet darauf hin, da? Solaris bei einem fork() sofort alle Seiten
> kopiert, auch, wenn diese eigentilch nie wieder anger?hrt werden. Das
> macht Linux eben genau andersherum - Kopie wird bei schreibendem Zugriff
> angelegt.

Ist das eine Vermutung oder Wissen?? Selbst beim alten
System V Release 3.2 (auf dem z.B. SCO server basiert) wurde
solch ein Schwachsinn nicht mehr gemacht. Solaris basiert auf
System V Release 4.

> 
> Solaris:	Nach dem fork() l?uft ein Proze? sofort mit voller
> 		Geschwindigkeit los, daf?r hast Du beim fork() selbst
> 		eine recht hohe Latenz.
> Linux:		Fork ist *schnell*, aber das weitere Laufenlassen des
> 		Programmes danach hat nicht die volle Geschwindigkeit,
> 		da zwischendurch noch Seiten, auf die geschrieben wird,
> 		kopiert werden m?ssen.

Das nennt man Copy-on-write und ist uebliche Praxis bie Solaris UND
linux.

> 
> Nun, was ist der gro?e Unterschied? Ganz einfach: Linus(!) denkt, da?
> jemand, der fork()t, sowieso in Naher Zukunft exec() aufrufen m?chte.
> Also kann man's sich sparen, erst den ganzen Proze? zu kopieren.

Das ist die Philosophie des alten vfork-Aufrufes, der zu Zeiten erfunden
wurde als virtuelle Speicherverwaltung noch ein Fremdwort war und
beim Auslagern eines Prozesses wirklich der GANZE Prozess auf die
Platte geschrieben wurde (das nennt man swappen).

Der einzige Grund warum ein fork langsamer als der clone fuer einen
Thread ist, das bei einem fork die page-Table caches fuer den neuen
Prozess geloescht werden muessen. Bei einem Thread bleiben diese
unveraendert, da sich die Speicherverwltung ja nicht geaendert hat.

Gruss

Ihno





Mehr Informationen über die Mailingliste linux-l