Beate Kaufländle: Problem(e) mit Threads unter GNU/Linux

Hi ihr lieben,

ich schreibe gerade ein Programm unter GNU/Linux mit C++.
Dieses Programm erzeugt sehr viele Threads.
Ich sollte vielleicht kurz erklären wie die Threads erzeugt werden.

Zunächst einmal werden alle Threads mit pthread_create() erzeugt.

Also es gibt den Hauptprozess der zunächst einen Thread startet.
Dieser Thread erzeugt weitere Threads. Diese Threads laufen aber nur so lange bis sie ihre Aufgabe erfüllt haben.

Nun habe ich aber das Problem das irgendwann das erzeugen von weiteren Threads fehlschlägt.
Was ganz und gar nicht akzeptabel ist. Es ist nämlich wichtig das _jeder_ Thread gestartet wird und seine Aufgabe erfüllt.

Vielleicht sollte ich noch etwas erwähnen. Der Thread, (der vom Hauptprozess gestartet wird), hört einen bestimmten Port ab und gibt die Anfrage an Kind-Threads weiter und lauscht dann weiter an dem Port.
Also es ist sowas was man auch gerne Server nennt.

Eine Idee die ich hätte wäre nun das der Hauptprozess eine bestimmte Anzahl von Threads startet z. B. 16. Nun lauscht der 1. Thread auf dem Port, kommt eine Anfrage startet er den Kind-Thread und zugleich beginnt der Thread 2 auf demselben Port zu lauschen usw.
Wenn Thread 16 dran war beginnt das ganze wieder von vorne. Wenn dann jeder Thread eine bestimmte Zeit aktiv war wird er vom Hauptprozess beendet und dafür wird ein neuer Thread gestartet.
So dass man immer 16 Threads aktiv hat.

Würde sowas in der Art mein Problem lösen?
Was haltet ihr von diesem "Threadmanagment"?
Wie entsteht überhaupt mein Problem?
Warum können keine Threads mehr erzeugt werden?
Was könnt ihr mir zur Abhilfe vorschlagen?
Macht Apache nicht sowas ähnliches?
Wie wird es dort gelöst?

Beate Kaufländle

  1. Hallo,

    Nun habe ich aber das Problem das irgendwann das erzeugen von weiteren Threads fehlschlägt.

    Wie viele Threads erzeugst Du denn? 300 Threads pro Prozess sollten selbst bei wenig Speicher problemlos möglich sein, wenn Du die Stack-Size reduzierst, dann weitaus mehr (dafür ist das mögliche Verschachtelungsniveau von Funktionsaufrufen nicht mehr so groß). Und wenn Du mehr Threads brauchst, dann solltest Du Dein Konzept etwas überdenken...

    Vielleicht sollte ich noch etwas erwähnen. Der Thread, (der vom Hauptprozess gestartet wird), hört einen bestimmten Port ab und gibt die Anfrage an Kind-Threads weiter und lauscht dann weiter an dem Port.
    Also es ist sowas was man auch gerne Server nennt.

    Wenn Du Netzwerkserver implementierst, willst Du Dir evntuell das Worker-Modell ansehen (bitte auch die Links am Ende der Seite beachten).

    Macht Apache nicht sowas ähnliches?

    Für den Apache gibt es verschiedene Implementierungen:

    - mpm_worker: Das setzt das Worker-Modell mit Threads um (so wie ich's Dir
                   vorgeschlagen habe).
     - mpm_prefork: Das setzt auch das Worker-Modell ein, ALLERDINGS nutzt es
                    KEINE Threads, sondern separate Prozesse. Damit das ganze
                    funktioniert, werden Dateideskriptoren zwischen den
                    Prozessen hin- und hergeschoben, das geht dann schon etwas
                    tiefer in die Systemprogrammierung unter UNIX ein
                    (siehe dazu auch das Buch Stevens, Advanced Programming in
                    the UNIX Environment)
     - und noch weitere, in der Praxis weniger relevante...

    Viele Grüße,
    Christian