Abrí el Administrador de tareas y busqué debajo del área "Sistema" y vi:
Subprocesos: 1337
Como tengo un procesador de doble núcleo con hiperprocesamiento disponible (es decir, cuatro subprocesos), ¿cómo es posible tener más de 1000 subprocesos cuando se supone que mi procesador solo tiene cuatro?
cpu
threads
hyper-threading
dpl47
fuente
fuente
Respuestas:
La respuesta simple es que no todos los hilos se ejecutan simultáneamente. Para una explicación más completa, sigue leyendo.
El planificador de tareas del sistema operativo generalmente está pensado para programar aplicaciones, y hacerlo le permite realizar una tarea mientras la computadora está trabajando en otra. En los viejos tiempos, la prueba de fuego de la multitarea era formatear un disquete mientras hacía otra cosa. Si realmente quisiera poner a prueba el sistema operativo, formatearía un disquete mientras descargaba un archivo a través de un módem conectado al puerto serie. A medida que el hardware se volvió lo suficientemente potente como para hacerlo de manera significativa, la reproducción de video a veces también apareció en tales pruebas. Si el programador de tareas del sistema operativo pudiera manejar esas tareas sin problemas, entonces podría manejar cualquier cosa.
Sin embargo, el programador de tareas en realidad no programa aplicaciones (procesos), programa hilos . Cada aplicación tiene al menos un subproceso, pero potencialmente puede usar una gran cantidad de subprocesos para dividir el trabajo que realiza en partes relacionadas o independientes. Por ejemplo, es común que una aplicación tenga un subproceso que maneje la interfaz de usuario y cree otro subproceso cuando el usuario inicie una operación potencialmente de larga duración (que podría ser la impresión, el recálculo de una hoja de cálculo, un entorno de desarrollo haciendo una búsqueda de símbolos, etc., etc.). Algunos entornos de programación introducen cierta cantidad de hilos invisiblemente para el programador; por ejemplo, Java y .NET pueden hacer recolección de basuraen un hilo separado, que está fuera del control inmediato del programador. Algunos programas crean una serie de subprocesos desde el principio y los agrupan, porque crear nuevos subprocesos es una operación relativamente costosa (por lo que no necesariamente tiene que crear un subproceso cada vez que lo necesite). Todo lo que hace una vista previa generalmente se realiza en un hilo separado, por lo que el resto de la interfaz de usuario sigue respondiendo mientras se genera la vista previa. Y así. En conjunto, todo esto significa que la cantidad de subprocesos en el sistema en cualquier momento puede ser fácilmente muchas veces la cantidad de procesos.
Cada hilo puede estar en uno de los pocos estados posibles, pero la distinción más importante es entre correr , ejecutable y esperando estados; La terminología puede variar ligeramente, pero esa es la idea general. En cualquier momento, solo se puede ejecutar un subproceso por núcleo virtual (debido a hyperthreading y tecnologías similares) CPU (es decir, ejecutar instrucciones de código de máquina), pero se puede ejecutar cualquier cantidad de subprocesos (lo que significa que es un candidato para obtener la CPU la próxima vez que el planificador necesite tomar una decisión sobre qué subproceso debe ejecutarse). Esperando (también conocido como bloqueado) los subprocesos son solo eso, esperando algo; los casos más comunes probablemente son que está esperando la E / S de red, disco o usuario (la entrada del usuario en particular es excepcionalmente lenta).
El recuento de subprocesos que ve en el administrador de tareas es el número total de subprocesos en cualquiera de estos estados. Por ejemplo, el sistema Windows 7 en el que estoy escribiendo esto actualmente tiene alrededor de 70 procesos iniciados pero casi 900 hilos. Con todos los procesos en segundo plano para manejar diversas tareas y cómo probablemente se subdividen en una multitud de hilos cada uno, este no es un número escandaloso.
Ir un poco más en las profundidades de la implementación técnica, en el núcleo mismo de un programador de tareas del sistema operativo preventivo multitarea suele ser algún tipo de enlace de interrupción de hardware. Esto significa que el kernel puede detener la CPU cuando no tiene trabajo útil que realizar (esta es seguramente una de las razones, si no la razón, por la que Linux verifica las
HLT
instrucciones de arranque en IA-32(CPU compatibles, y probablemente realiza comprobaciones similares en otras arquitecturas), seguro sabiendo que en algún momento futuro razonablemente determinado, se disparará una interrupción y se invocará el programador de tareas. Dado que la interrupción se dispara independientemente de qué otro trabajo esté realizando la CPU (esa es la idea detrás de las interrupciones), el planificador se ejecuta regularmente y tiene la oportunidad de determinar qué subproceso debe ejecutarse durante el siguiente intervalo de tiempo. Dado que los cambios de contexto son relativamente caros, generalmente es posible (al menos a través del código fuente) ajustar cuán agresivamente el planificador cambia entre hilos; el cambio de subprocesos con mayor frecuencia hace que el sistema sea más receptivo, pero la sobrecarga de cambio significa que el tiempo total para terminar un conjunto de tareas dado es más largo. El mas rapidoel sistema será uno que solo cambie entre subprocesos cuando el subproceso en ejecución ya no sea posible ejecutar (lo que significa que se bloquea esperando algo, o ha terminado su trabajo) porque eso minimiza la sobrecarga, mientras que el sistema más receptivo cambiará entre subprocesos cada vez que se invoca el planificador porque eso minimiza el tiempo promedio de espera antes de que un subproceso particular obtenga tiempo de CPU. La configuración ideal generalmente está en algún lugar entre estos dos, y la compensación entre esas opciones es probablemente una de las principales razones por las que Linux ofrece múltiples programadores para elegir, así como algunos parámetros de ajuste a través de la configuración del kernel.Los sistemas operativos y entornos multitarea cooperativos, por otro lado ( Windows 3.x es un ejemplo), confían en cada aplicación para ceder regularmente el control al programador. Por lo general, hay una función API específicamente destinada a hacer eso, y muchas veces las funciones API lo harán como parte de su flujo de ejecución interno, porque ayuda a que la experiencia del usuario sea más fluida. Ese enfoque de diseño funciona bien siempre y cuando todas las aplicaciones se comporten bien y cedan el control con intervalos cortos durante cualquier operación de ejecución prolongada (ejecución prolongada significa más de una pequeña fracción de segundo), pero una aplicación que no puede obstruirse Todo el sistema. Esta es una de las principales razones por las que Windows 3.x tuvo tan mal desempeño en la prueba multitarea que mencioné anteriormente, mientras que OS / 2paseó alegremente mientras realizaba las mismas tareas en el mismo hardware: una aplicación podía decirle a la unidad de disquete que escribiera un determinado sector, y el tiempo que tardó en hacerlo antes de que la llamada regresara pudiera ser medible (decenas a cientos de milisegundos o más); un sistema multitarea preventivo haría que su programador interrumpa en su próxima invocación programada, observe que el hilo que actualmente se está "ejecutando" en realidad está bloqueado por la llamada de escritura y simplemente cambie a otro hilo que sea ejecutable. (En la práctica es un poco más complicado, pero esa es la idea general).
En los entornos preventivos multitarea y cooperativos, también existe la posibilidad de que diferentes hilos tengan diferentes prioridades. Por ejemplo, probablemente sea más importante ejecutar de manera oportuna el subproceso que recibe datos a través de un enlace de comunicaciones que el que actualiza la visualización de la hora del sistema, por lo que el subproceso de recepción tiene alta prioridad y el subproceso de actualización de la pantalla de tiempo tiene baja prioridad . Las prioridades de los hilos juegan un papel en la decisión del planificador de qué hilo permitir ejecutar (por ejemplo, muy simplificado, los subprocesos de alta prioridad siempre deben ejecutarse antes que los subprocesos de baja prioridad, por lo que incluso si el subproceso de baja prioridad tiene trabajo por hacer, si el subproceso de alta prioridad se vuelve ejecutable, tiene prioridad), pero tales decisiones de programación específicas no afectan el diseño del mecanismo subyacente.
fuente
Piense en una carretera de cuatro carriles con 1037 vehículos.
Su sistema operativo necesita muchos procesos en ejecución para funcionar para muchos servicios. Incluso los programas gráficos más simples requerirán programación multiproceso. Cuando piensa en su gran cantidad de programas abiertos, ve que es necesario compartir los recursos de potencia informática.
Lo que muestra su administrador de tareas es la carga actual del sistema. Lo que muestran las especificaciones de comp es cuántos hilos se aceptan (en la interfaz) para ejecución paralela. Sin entrar mucho en la diferencia entre las características de hyperthreading y multinúcleo, con un hilo de interfaz más lógico que acepta, un sistema generalmente funcionará mejor.
fuente
DoEvents
, lo que procesaría la cola de mensajes, pero eso se hizo en el mismo hilo y bloquearía esa operación de larga duración hasta que se procesen todos los mensajes . (Por supuesto, puede llamar a las funciones de la API Win32 y / o crear procesos adicionales, pero en ese momento también puede usar uno de los idiomas de nivel inferior).Deberíamos dar un paso atrás y preguntarnos: ¿Cómo puede una computadora con una sola CPU tener dos hilos?
Los hilos son entidades de software, no hardware. Para tener otro subproceso, solo necesita memoria para los objetos que forman el subproceso, como una estructura de descriptor y una pila.
El sistema operativo cambia entre hilos en varios momentos, como dentro de ciertas interrupciones (como una interrupción del temporizador) o cuando los hilos hacen llamadas al sistema operativo.
De todos los subprocesos que existen en el sistema, solo un subconjunto generalmente se encuentra en un estado que comúnmente se llama "ejecutable". Los subprocesos ejecutables están ansiosos por ejecutarse: se están ejecutando o están sentados en una "cola de ejecución", esperando ser enviados por el planificador. Los subprocesos que no son ejecutables están "bloqueados", a la espera de adquirir algún recurso o recibir entrada, o "en reposo", que es como estar bloqueado en la entrada, donde la "entrada" es el paso del tiempo. Se produce un "cambio de contexto" cuando la función del planificador en el sistema operativo examina la cola de ejecución de un procesador y elige un subproceso diferente para ejecutar.
No se confunda con "hyperthreading" , que es el nombre de Intel para una característica de hardware en particular.
fuente