optimizar mi servidor Linux para manejar 10,000 hilos por proceso
Como otros explicaron, esto generalmente está mal. Un subproceso es un recurso costoso , especialmente porque tiene su propia pila de llamadas (generalmente, un megabyte) y porque es una tarea programable por el núcleo. Los hilos son aún más costosos que los descriptores de archivos abiertos .
Lea los sistemas operativos: tres piezas fáciles (libro de texto de descarga gratuita).
Como regla general, no desea tener muchos subprocesos, y ciertamente no muchos subprocesos ejecutables. El número de subprocesos ejecutables generalmente debe ser como máximo el número de núcleos (o un pequeño múltiplo de eso), por lo que aproximadamente una docena como máximo. El número de subprocesos en un proceso podría ser ligeramente mayor. Entonces, a menos que tenga un servidor muy expansivo (con muchos zócalos y núcleos de procesador), no querrá tener más de una docena de subprocesos ejecutables y cien subprocesos (la mayoría de ellos están inactivos) en su proceso (en su escritorio) .
En Linux, los subprocesos y los procesos son muy similares (ya que ambos pueden ser creados por el clon (2) ) y ambos son tareas programadas por el núcleo. En realidad, el planificador del núcleo está programando tareas que pueden ser subprocesos dentro de un proceso de subprocesos múltiples, o el subproceso principal único de un proceso de subproceso único (en ese caso, nombrará "procesar" ese subproceso único) o subprocesos del núcleo. Probablemente no desee tener más de mil tareas programables en total en su sistema de escritorio.
En Linux, un proceso es simplemente un grupo de subprocesos que comparten el mismo espacio de direcciones virtuales (y comparten otras cosas, como la tabla de descriptores de archivos, etc.). Algunos procesos tienen solo un hilo.
Un espacio de direcciones virtuales se define por Wikipedia como
"el conjunto de rangos de direcciones virtuales que un sistema operativo pone a disposición de un proceso"
(pero vea también esta respuesta que explica que la terminología no es universal, y parte de la documentación de Microsoft usa una definición diferente e incompatible ).
En Linux, proc (5) es útil para comprender el espacio de direcciones virtuales de algunos procesos. Prueba ambos
cat /proc/self/mapsy cat /proc/$$/mapsen una terminal. Vea también esto , y pmap (1) y ps (1) y top (1) .
Todos los programas de espacio de usuario se ejecutan en algún proceso y usan memoria virtual, por lo que cada proceso tiene su propio espacio de dirección virtual. La RAM física es un recurso administrado por el kernel de Linux, y las aplicaciones no tienen acceso directo a la RAM (excepto por mmap (2) -ing /dev/mem, ver mem (4) ).
Entonces, un proceso no usa directamente RAM. Utiliza memoria virtual y tiene su propio espacio de direcciones virtuales. El kernel utiliza la paginación para administrar páginas físicas de RAM y proporcionar el espacio de direcciones virtuales y las abstracciones del proceso . En cualquier momento (incluso cuando su proceso está inactivo o cuando se está ejecutando), el núcleo podría extraer algunas páginas (por ejemplo, intercambiarlas en el disco). El núcleo está configurando la MMU (y manejando las excepciones de hardware de página perdidas en algún controlador de interrupciones , ya sea recuperando la página del disco o propagando una falla de segmentación al proceso, vea la señal (7) )
Podría tener hilos verdes por encima de los hilos del sistema (pero las bibliotecas de hilos verdes son difíciles de implementar y depurar). Mire las gorutinas utilizadas en Go para obtener un ejemplo elegante. Ver también setcontext (3) .
A veces, su sistema puede experimentar golpes . Esto sucede cuando la memoria virtual total (necesaria para todos los procesos) excede, en gran medida, la RAM física disponible. Entonces su computadora deja de responder. Lea sobre el tamaño del conjunto residente , la paginación de demanda , el conjunto de trabajo , el compromiso excesivo de memoria , ASLR .
Ver también -para Linux- fork (2) , clone (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , credentials (7) , pthreads (7) , futex (7) , capacidades (7) .