optimiser mon serveur Linux pour gérer 10 000 threads par processus
Comme d'autres l'ont expliqué, c'est généralement faux. Un thread est une ressource coûteuse , notamment parce qu'il a sa propre pile d'appels (typiquement, un mégaoctet) et parce que c'est une tâche programmable par le noyau. Les threads sont encore plus coûteux que les descripteurs de fichiers ouverts .
Lire Systèmes d'exploitation: trois pièces faciles (manuel téléchargeable gratuitement).
En règle générale, vous ne voulez pas avoir beaucoup de threads, et certainement pas beaucoup de threads exécutables. Le nombre de threads exécutables doit généralement être au plus le nombre de cœurs (ou un petit multiple de cela), donc environ une douzaine au plus. Le nombre de threads dans un processus peut être légèrement supérieur. Donc, à moins d'avoir un serveur très étendu (avec de nombreux sockets et cœurs de processeur), vous ne voulez pas avoir plus d'une douzaine de threads exécutables et une centaine de threads (la plupart étant inactifs) dans votre processus (sur votre bureau) .
Sous Linux, les threads et les processus sont très similaires (car les deux peuvent être créés par clone (2) ) et les deux sont des tâches planifiées par le noyau. En fait, le planificateur du noyau planifie des tâches qui peuvent être des threads à l'intérieur d'un processus multithread, ou le thread principal unique d'un processus à thread unique (dans ce cas, vous nommerez "traiter" ce thread unique), ou les threads du noyau. Vous ne voulez probablement pas avoir plus d'un millier de tâches programmables au total sur votre système de bureau.
Sous Linux, un processus est simplement un groupe de threads partageant le même espace d'adressage virtuel (et partageant d'autres choses, comme une table de descripteurs de fichiers, etc ...). Certains processus n'ont qu'un seul thread.
Un espace d'adressage virtuel est défini par Wikipedia comme
"l'ensemble des plages d'adresses virtuelles qu'un système d'exploitation met à la disposition d'un processus"
(mais voir également cette réponse expliquant que la terminologie n'est pas universelle et que certains documents Microsoft utilisent une définition différente et incompatible ).
Sous Linux, proc (5) est utile pour comprendre l'espace d'adressage virtuel de certains processus. Essayez les deux
cat /proc/self/maps
et cat /proc/$$/maps
dans un terminal. Voir aussi ceci , et pmap (1) & ps (1) & top (1) .
Tous les programmes de l'espace utilisateur s'exécutent dans certains processus et utilisent de la mémoire virtuelle afin que chaque processus ait son propre espace d'adressage virtuel. La RAM physique est une ressource gérée par le noyau Linux, et les applications n'ont pas d'accès direct à la RAM (sauf par mmap (2) -ing /dev/mem
, voir mem (4) ).
Un processus n'utilise donc pas directement de RAM. Il utilise la mémoire virtuelle et possède son propre espace d'adressage virtuel. Le noyau utilise la pagination pour gérer les pages RAM physiques et fournir l'espace d'adressage virtuel et les abstractions de processus . À tout moment (même lorsque votre processus est inactif ou en cours d'exécution), le noyau peut paginer certaines pages (par exemple les échanger sur le disque). Le noyau configure la MMU (et gère les exceptions matérielles de manque de page dans un gestionnaire d'interruption , soit en récupérant la page à partir du disque, soit en propageant une erreur de segmentation au processus, voir signal (7) )
Vous pouvez avoir des threads verts au-dessus des threads système (mais les bibliothèques de threads verts sont difficiles à implémenter et à déboguer). Regardez dans les goroutines utilisées dans Go pour un exemple de fantaisie. Voir aussi setcontext (3) .
Parfois, votre système peut expérimenter le thrashing . Cela se produit lorsque la mémoire virtuelle totale (nécessaire à tous les processus) dépasse - par un facteur important - la RAM physique disponible. Ensuite, votre ordinateur ne répond plus. En savoir plus sur la taille de l'ensemble résident , la pagination de la demande , l' ensemble de travail , le sur- engagement de mémoire , l' ASLR .
Voir aussi -pour Linux- fork (2) , clone (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , informations d'identification (7) , pthreads (7) , futex (7) , capacités (7) .