1. Resumen del hilo
Los subprocesos son la unidad de ejecución básica para la ejecución del programa. Cuando el sistema operativo (excluidos los sistemas operativos de un solo subproceso, como los primeros DOS de Microsoft) ejecuta un programa, se establecerá un proceso en el sistema y, en este proceso, se debe establecer al menos un subproceso (este subproceso se denomina principal). thread). thread) como punto de entrada para la ejecución de este programa. Por tanto, cualquier programa que se ejecute en el sistema operativo tiene al menos un hilo principal.
Los procesos y los subprocesos son dos modelos operativos esenciales en los sistemas operativos modernos. Puede haber múltiples procesos en el sistema operativo, incluidos procesos del sistema (procesos creados internamente por el sistema operativo) y procesos de usuario (procesos creados por programas de usuario) que pueden tener uno o más subprocesos. No hay memoria compartida entre procesos, lo que significa que los procesos del sistema se ejecutan en sus propios espacios de memoria independientes. Los subprocesos de un proceso pueden compartir el espacio de memoria asignado por el sistema al proceso.
Los subprocesos no solo pueden compartir la memoria del proceso, sino que también tienen su propio espacio de memoria. Este espacio de memoria también se denomina pila de subprocesos y lo asigna el sistema cuando se crea el subproceso. datos utilizados dentro del hilo, como la pila de hilos. Variables definidas en la función de ejecución.
Nota: Cualquier hilo ejecutará una función cuando se cree. Esta función se llama función de ejecución de hilo. Esta función también puede considerarse como el punto de entrada del hilo (similar a la función principal del programa). No importa qué lenguaje o tecnología se utilice para crear un hilo, esta función debe ejecutarse (la expresión de esta función puede ser diferente, pero siempre existirá). Por ejemplo, el tercer parámetro de la función API CreateThread utilizada para crear un hilo en Windows es el puntero de esta función de ejecución.
Después de que el sistema operativo divide el proceso en varios subprocesos, estos subprocesos se pueden ejecutar simultáneamente bajo la administración del sistema operativo, lo que mejora en gran medida la eficiencia de ejecución del programa. Aunque desde una perspectiva macro la ejecución de subprocesos parece que se ejecutan varios subprocesos al mismo tiempo, en realidad esto es solo un encubrimiento del sistema operativo. Dado que una CPU sólo puede ejecutar una instrucción a la vez, es imposible ejecutar dos tareas al mismo tiempo en una computadora con una CPU. Para mejorar la eficiencia de ejecución del programa, el sistema operativo eliminará un subproceso cuando esté inactivo y permitirá que otros subprocesos lo ejecuten. Este método se denomina programación de subprocesos. La razón por la que vemos varios subprocesos ejecutándose al mismo tiempo en la superficie es porque el tiempo para cambiar entre diferentes subprocesos es muy corto y, en circunstancias normales, el cambio es muy frecuente. Supongamos que tenemos los hilos A y B. En tiempo de ejecución, puede ser que después de que A se ejecute durante 1 milisegundo, después de cambiar a B, B se ejecute durante otro 1 milisegundo, luego cambie a A y A se ejecute durante otro 1 milisegundo. Dado que 1 milisegundo es difícil de percibir para la gente común, en la superficie parece que A y B se ejecutan al mismo tiempo, pero en realidad A y B se ejecutan alternativamente.
2. Los beneficios que nos aportan los hilos
El uso adecuado de subprocesos puede reducir los costos de desarrollo y mantenimiento e incluso mejorar el rendimiento de aplicaciones complejas. Por ejemplo, en las aplicaciones GUI, los eventos se pueden procesar mejor mediante la naturaleza asincrónica de los subprocesos; en los programas de servidor de aplicaciones, se pueden establecer múltiples subprocesos para manejar las solicitudes de los clientes. Los subprocesos pueden incluso simplificar la implementación de máquinas virtuales. Por ejemplo, el recolector de basura de la máquina virtual Java (JVM) generalmente se ejecuta en uno o más subprocesos. Por tanto, el uso de hilos mejorará nuestras aplicaciones en los siguientes cinco aspectos:
1. Aprovechar al máximo los recursos de la CPU
La mayoría de las computadoras en el mundo ahora tienen una sola CPU. Por lo tanto, es particularmente importante aprovechar al máximo los recursos de la CPU. Al ejecutar un programa de un solo subproceso, la CPU puede estar inactiva mientras el programa está bloqueado. Esto provocará un gran desperdicio de recursos informáticos. El uso de subprocesos múltiples en un programa puede ejecutar otros subprocesos cuando un subproceso está inactivo o bloqueado y la CPU está inactiva. De esta forma, es difícil que la CPU esté inactiva. Por lo tanto, los recursos de la CPU se utilizan por completo.
2. Simplificar el modelo de programación.
Si el programa solo completa una tarea, simplemente escriba un programa de un solo subproceso y escriba el código de acuerdo con los pasos para realizar la tarea. Pero para completar múltiples tareas, si todavía usa un solo hilo, debe determinar en el programa si se debe ejecutar cada tarea y cuándo. Por ejemplo, muestra las horas, minutos y segundos de un reloj. Si usa un solo hilo, debe juzgar el tiempo de rotación y el ángulo de estos tres punteros uno por uno en el bucle. Si se utilizan tres subprocesos para manejar la visualización de estos tres punteros, significa realizar una tarea separada para cada subproceso. Esto ayuda a los desarrolladores a comprender y mantener el programa.
3. Simplifique el procesamiento de eventos asincrónicos.
Cuando una aplicación de servidor recibe diferentes conexiones de cliente, la forma más sencilla de manejarlo es crear un hilo para cada conexión de cliente. El hilo de escucha sigue siendo responsable de escuchar las solicitudes del cliente. Si este tipo de aplicación es procesada por un solo hilo, cuando el hilo de escucha recibe una solicitud del cliente, comienza a leer los datos enviados por el cliente. Después de leer los datos, el método de lectura se bloquea, es decir, este hilo. Will Ya no podrá escuchar las solicitudes de los clientes. Si desea manejar múltiples solicitudes de clientes en un solo subproceso, debe usar conexiones de socket sin bloqueo y E/S asíncronas. Sin embargo, el uso de E/S asíncronas es más difícil de controlar y más propenso a errores que el uso de E/S síncronas. Por lo tanto, los eventos asincrónicos, como solicitudes múltiples, se pueden manejar más fácilmente utilizando E/S sincrónicas y de subprocesos múltiples.
4.Hacer la GUI más eficiente
Cuando se utiliza un solo hilo para procesar eventos de GUI, se debe usar un bucle para buscar eventos de GUI que puedan ocurrir en cualquier momento. Dentro del bucle, además de buscar eventos de GUI, se deben ejecutar otros códigos de programa. Si el código es demasiado largo, los eventos de la GUI se "congelarán" hasta que se ejecute el código.
En los marcos de GUI modernos (como SWING, AWT y SWT), se utiliza un subproceso de envío de eventos (EDT) separado para escanear eventos de GUI. Cuando presionamos un botón, la función de evento de clic del botón se llamará en este hilo de envío de eventos. Dado que la tarea de EDT es únicamente escanear eventos de la GUI, la respuesta a los eventos de esta manera es muy rápida.
5. Ahorro de costes
Generalmente existen tres métodos para mejorar la eficiencia de la ejecución del programa:
(1) Aumente la cantidad de CPU en la computadora.
(2) Iniciar múltiples procesos para un programa
(3) Utilice múltiples procesos en el programa.
El primer método es el más sencillo de realizar, pero también el más caro. Este método no requiere modificación del programa. En teoría, cualquier programa puede utilizar este método para mejorar la eficiencia de ejecución. Aunque el segundo método no requiere la compra de hardware nuevo, no es fácil compartir datos. Si la tarea que debe completar este programa requiere compartir datos, este método no es conveniente e iniciar varios subprocesos consumirá una gran cantidad de sistema. recursos. El tercer método simplemente compensa las deficiencias del primer método, al tiempo que hereda sus ventajas. En otras palabras, no es necesario comprar una CPU ni ocupará muchos recursos del sistema al iniciar demasiados subprocesos (de forma predeterminada, el espacio de memoria ocupado por un subproceso es mucho menor que el espacio de memoria ocupado por un proceso). Múltiple) y el subproceso múltiple pueden simular el modo de ejecución de múltiples CPU. Por lo tanto, el uso de subprocesos múltiples es la forma más económica de mejorar la eficiencia de ejecución del programa.
3. Modelo de hilo Java
Dado que Java es un lenguaje puramente orientado a objetos, el modelo de subprocesamiento de Java también está orientado a objetos. Java encapsula todas las funciones necesarias de los subprocesos a través de la clase Thread. Para crear un hilo, debe haber una función de ejecución de hilo. Esta función de ejecución de hilo corresponde al método de ejecución de la clase Thread. La clase Thread también tiene un método de inicio, que es responsable de establecer un hilo, lo que equivale a llamar a la función de creación de hilos de Windows CreateThread. Cuando se llama al método de inicio, si el subproceso se establece correctamente, se llama automáticamente al método de ejecución de la clase Thread. Por lo tanto, cualquier clase Java que herede Thread puede crear un hilo a través del método de inicio de la clase Thread. Si desea ejecutar su propia función de ejecución de subprocesos, debe anular el método de ejecución de la clase Thread.
Además de la clase Thread en el modelo de subprocesos de Java, también hay una interfaz Runnable que identifica si una clase Java se puede utilizar como clase de subproceso. Esta interfaz solo tiene un método abstracto ejecutado, que es la función de ejecución de subprocesos de Java. modelo de hilo. Por lo tanto, el único criterio para una clase de subproceso es si la clase implementa el método de ejecución de la interfaz Runnable. En otras palabras, una clase con una función de ejecución de subproceso es una clase de subproceso.
Como se puede ver en lo anterior, hay dos formas de crear subprocesos en Java. Una es heredar la clase Thread y la otra es implementar la interfaz Runnable y crear subprocesos a través de Thread y la clase que implementa Runnable. Estos dos métodos son esencialmente Se dice que es un método, es decir, el hilo se crea a través de la clase Thread y se ejecuta el método de ejecución. Pero su gran diferencia es que los subprocesos se crean heredando la clase Thread. Aunque es más fácil de implementar, dado que Java no admite la herencia múltiple, si esta clase de subproceso hereda Thread, no puede heredar otras clases. Por lo tanto, el modelo de subprocesos de Java proporciona. métodos para establecer subprocesos mediante la implementación de la interfaz Runnable, de modo que las clases de subprocesos puedan heredar clases relacionadas con el negocio en lugar de la clase Thread cuando sea necesario.