Mehrere Threads (> 50.000) Linux

MArc

Erfahrenes Mitglied
Wunderschönen guten Abend die Herrn, die Damen,

ich hätte da mal ein Problem, bei dem ich jetzt Hilfe brauch.

Mein Ziel:
Ein (linux) Tcp Server, der jede Verbindung an einen Thread übergibt und dort verarbeitet.

Nun ist mein Problem, dass mein Test-Code auf meine lokalen Maschine( arch linux)
max. 380 Threads zulässt.

ulimit -a sagt mit jedoch, dass ich 100.000 starten darf.
Code:
$ cat /proc/sys/kernel/threads-max 
100000

Mein Testcode:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

using namespace std;

void *init( void *ptr );

main(){
    pthread_t thread;
    int threadCount = 0;
    int ret;
    while(true) {
      ret = pthread_create( &thread, NULL, &init, (void*)threadCount );
      threadCount++;
    }
    exit(0);
}

void *init( void *ptr )
{
     int *count;
     count = (int*) ptr;
     printf("Thread #%d\n", count );
}

Letzte Ausgabezeile:
Code:
Thread #380
Danach wirft pthread_create error-code 11.

( Was ich auch mal recht interessant finden würde, ist, wo ich nachschauen kann,
was genau dieser error-code bedeutet)

Any hints ?

Grüße,
MArc
 
Vieleicht gibt es jemand der dir bei deinem Problem konkret helfen kann. Ich kann es leider nicht.
Du solltest dir das aber noch einmal gut überlegen. 50000 Threads scheint mir ein "wenig" viel, da stimmt was mit deiner Software archetektur nicht. Du darfst nicht vergessen, auch bei Linux besitzten Thread einen extra overhead, welcher bei 50000threads ernorm sein darf. Da du (vermutlich) keinen Server/PC mit sovielen CPU-Kernen besitzt, scheint das Ziel auch die Parallisierung zu sein.

Ich vermute das dein Probleme, in der Blockierung von send() und recv() liegt, dazu soltest du dir mal die select() funktion anschauen.

mfg
SGSSGene
 
Nacht,

dieses "Select", ich neheme mal an, Du spricht von dem "SelectManger", hatte ich bereits
aus einem Digital Mars D Beispiel angeschaut.

Ist das das Maß aller Dinge in TCP-Server?

Was ich mich nun Frage ist wohl, gelingt mir das *überhaupt* einen TCP-Server zu erstellen,
der bei einem Quad-Core 3* Ghz bei über eine halbe Millionen Clients lauffähig ist - sprich
performance-maesig stabil bleibt ?

... oder ist es zwingen notwendig, die Arbeit auf mehrere Server zu verteilen ? (Thread bleib i.d.R. 24H am leben, tut kleine Strinoperationen und stirbt dann )

Werden Threads wie ein eigener Prozess am OS registriert? Wenn nein, dann könnte man doch pro Prozess mehrere Threads starten und so dieses Limit umgehen ?

Fragen über Fragen ...

Grüße,
MArc
 
Zuletzt bearbeitet:
Also Threads sind "Subprozesse" eines Prozesses. Ich weiß nicht, vermute aber das du damit das Limit umgehen kann.
Ich weiß nicht ob select() Maß aller Dinge ist, lässt sich aber auch für UDP verbindungen nutzen.
Es gibt noch "nicht blockierende Sockets", das kommt aber für dich nicht in frage, da viele "Poll" anfragen gemacht werden.

Hab so was ähnliches vor kurzen in einem anderem Forum gefragt und folgende Antwort bekommen:
Wenn du das letzte Tröpfchen Performance rausholen willst, solltest du dir epoll (unter Linux) oder den I/O-Completion Port (unter Windows) ansehen. (Um das ständige Pollen zu vermeiden.)
Link zum ZFX Thema

Ich weiß nicht ob es realisitisch ist eine halbe million Clients über TCP zu bertreiben...

mfg
SGSSGene
 
Zuletzt bearbeitet:
Danke.

Vielleicht noch einmal zur ursprünglichen Frage:

Wieso lässt mein Linux nicht mehr Threads als 380 zu ?
Auf einem anderen System waren es weniger, sprich, es hängt wohl an der Hardware..
Aber 380 ist imho ziemlich wenig.

Jemand eine Idee ?

Grüße,
MArc
 
Hi.

Welche Kernel Version hast du denn?

Hab mal schnell gesucht:
The maximum number of threads available is determined by the minimum
of:

- The user processes setting (ulimit -u) in
/etc/security/limits.conf

- The limit MAX_TASKS_PER_USER defined in
/usr/include/linux/tasks.h (change requires Linux kernel to be
recompiled)

- The limit PTHREAD_THREADS_MAX defined in libpthreads.so
(change requires Linux kernel to be recompiled)

Dann schau mal in /usr/include/bits/local_lim.h nach Macros wie PTHREAD_THREADS_MAX oder _POSIX_THREAD_THREADS_MAX.

Auf meinem System kann ich problemlos mehr als 13000 Threads kreieren (dann hab ich abgebrochen).

Wg. des Error Codes: laut Manpage wird nur EAGAIN als Fehlercode zurückgegeben.


Gruß

\edit: Sorry, ich hab mir dein Testprogramm erst jetzt genauer angeschaut. Dabei sind die meisten Threads ja schon beendet. Das ist dann natürlich kein richtiger Test um die max. Anzahl von Threads zu bestimmen. Wenn ich dafür sorge, das die Threads nicht gleich nach der Ausgabe terminieren, dann kann ich auf meinem System 8067 Threads kreieren. Mein ulimit Eintrag ist 8183 und ein paar andere Prozesse laufen natürlich auch schon...
 
Zuletzt bearbeitet:
Welche Kernel Version hast du denn?

Hi,

ich habe die Version "Linux bruce 2.6.26-ARCH #1 SMP PREEMPT".

Dann schau mal in /usr/include/bits/local_lim.h nach Macros wie PTHREAD_THREADS_MAX oder _POSIX_THREAD_THREADS_MAX.
Den Ordner /usr/include/bits hab' ich nicht.
In "/etc/security/limits.conf" ist keine Limitierung auf Thread vorhanden.
"/usr/include/linux/tasks.h" gibt es bei mir nicht und ein grep nach "THREADS"
gab nur folgendes aus:
Code:
$ grep "THREADS" /usr/include/linux/ -rin
/usr/include/linux/wait.h:11:#define __WNOTHREAD        0x20000000      /* Don't wait on children of other threads in this group */
/usr/include/linux/sysctl.h:123:        KERN_MAX_THREADS=39,    /* int: Maximum nr of threads in the system */
/usr/include/linux/sysctl.h:182:        VM_NR_PDFLUSH_THREADS=15, /* nr_pdflush_threads */
/usr/include/linux/nfsd/syscall.h:39:   int                     svc_nthreads;
/usr/include/linux/nfsd/stats.h:25:     unsigned int    th_cnt;         /* number of available threads */
/usr/include/linux/nfsd/stats.h:27:                                      * of available threads were in use */

\edit: Sorry, ich hab mir dein Testprogramm erst jetzt genauer angeschaut. Dabei sind die meisten Threads ja schon beendet. Das ist dann natürlich kein richtiger Test um die max. Anzahl von Threads zu bestimmen. Wenn ich dafür sorge, das die Threads nicht gleich nach der Ausgabe terminieren, dann kann ich auf meinem System 8067 Threads kreieren. Mein ulimit Eintrag ist 8183 und ein paar andere Prozesse laufen natürlich auch schon...
Logisch, dass kein richtiger Test entsteht, jedoch umso verwunderlicher, dass er bei mir bei 380 stehen bleibt, wenn doch die Threads kurz danach sterben.
Mein ulimi- u spuckt ähnliche Zahlen aus: 8126.

Gruß und Danke,
MArc
 
Zuletzt bearbeitet:
Hi.

Wie es scheint benutzt nicht die glibc (/usr/include/bits sollte eigentlich vorhanden sein).

Wenn du eine andere C Bibliothek nimmst, kann es durchaus sein, dass das Maximum von Threads pro Prozess bei 64 liegt (POSIX Standardwert). Die Threads sterben natürlich langsamer als sie kreiert werden und ein Faktor von 6 scheint mir durchaus realistisch.

Gruß
 
Hm, Danke klingt logisch.

Dann werde ich mal prüfen, an was das liegt und welche lib ich nutz.

Grüße,
MArc
 
Zurück