Una suave introducción al subproceso múltiple.
Una breve discusión sobre la tecnología de subprocesos múltiples.
Una suave introducción al subproceso múltiple
Una breve discusión sobre la tecnología de subprocesos múltiples.
Acercándonos al mundo de la concurrencia, paso a paso. Acércate al mundo de la concurrencia paso a paso.
Las computadoras modernas tienen la capacidad de realizar múltiples operaciones al mismo tiempo. Respaldada por avances de hardware y sistemas operativos más inteligentes, esta característica hace que sus programas se ejecuten más rápido, tanto en términos de velocidad de ejecución como de capacidad de respuesta. Las computadoras modernas tienen la capacidad de realizar múltiples operaciones simultáneamente. Impulsada por mejoras de hardware y un sistema operativo inteligente, esta característica hace que los programas se ejecuten más rápido, tanto en términos de velocidad de ejecución como de capacidad de respuesta.
Escribir software que aproveche tal poder es fascinante, pero complicado: requiere que usted comprenda lo que sucede bajo el capó de su computadora. En este primer episodio intentaré arañar la superficie de los hilos, una de las herramientas que proporcionan los sistemas operativos para realizar este tipo de magia. ¡Vamos! Escribir software que aproveche este poder es fascinante, pero también complicado: requiere que usted comprenda lo que sucede detrás de escena de su computadora. En este artículo intentaré arañar la superficie de los hilos, una herramienta proporcionada por el sistema operativo para realizar esta función mágica. ¡Empecemos!
Procesos e hilos: nombrar las cosas de la manera correcta
Procesos e hilos: nómbrelos de la manera correcta
Los sistemas operativos modernos pueden ejecutar varios programas al mismo tiempo. Es por eso que puedes leer este artículo en tu navegador (un programa) mientras escuchas música en tu reproductor multimedia (otro programa). Cada programa se conoce como un proceso que se está ejecutando. El sistema operativo conoce muchos trucos de software para hacer que un proceso se ejecute junto con otros, además de aprovechar el hardware subyacente. De cualquier manera, el resultado final es que sentirá que todos sus programas se ejecutan simultáneamente. Los sistemas operativos modernos pueden ejecutar múltiples programas simultáneamente. Es por eso que puedes leer este artículo en tu navegador (un programa) mientras escuchas música en tu reproductor multimedia (otro programa). Cada programa se llama proceso en ejecución. El sistema operativo conoce muchos trucos de software para hacer que los procesos se ejecuten junto con otros procesos y aprovechar el hardware subyacente. De cualquier manera, el resultado final es que sentirás que todos tus programas se ejecutan simultáneamente.
Ejecutar procesos en un sistema operativo no es la única forma de realizar varias operaciones al mismo tiempo. Cada proceso es capaz de ejecutar subtareas simultáneas dentro de sí mismo, llamadas subprocesos. Puedes pensar en un hilo como una parte del proceso en sí. Cada proceso activa al menos un hilo al inicio, que se denomina hilo principal. Luego, según las necesidades del programa/programador, se pueden iniciar o finalizar subprocesos adicionales. El multiproceso consiste en ejecutar varios subprocesos dentro de un solo proceso. Ejecutar procesos dentro de un sistema operativo no es la única forma de realizar múltiples operaciones simultáneamente. Cada proceso es capaz de ejecutar subtareas simultáneamente dentro de sí mismo, llamadas subprocesos. Puedes pensar en los hilos como parte del proceso en sí. Cada proceso activa al menos un hilo cuando se inicia, llamado hilo principal. Luego, dependiendo de las necesidades del programa/programador, se pueden iniciar o finalizar otros subprocesos. Multithreading se refiere a ejecutar múltiples threads en un proceso.
Por ejemplo, es probable que su reproductor multimedia ejecute varios subprocesos: uno para representar la interfaz (suele ser el subproceso principal), otro para reproducir la música, etc. Por ejemplo, su reproductor multimedia puede ejecutar varios subprocesos: uno para representar la interfaz (normalmente es el subproceso principal), otro para reproducir música, etc.
Puede pensar en el sistema operativo como un contenedor que contiene múltiples procesos, donde cada proceso es un contenedor que contiene múltiples subprocesos. En este artículo me centraré únicamente en los hilos, pero todo el tema es fascinante y merece un análisis más profundo en el futuro. Puede pensar en el sistema operativo como un contenedor con múltiples procesos, donde cada proceso es un contenedor con múltiples subprocesos. En este artículo me centraré sólo en los hilos, pero el tema general es fascinante y merece un análisis más profundo en el futuro.

- Los sistemas operativos pueden verse como una caja que contiene procesos, que a su vez contienen uno o más subprocesos.
Las diferencias entre procesos e hilos.
Diferencia entre proceso e hilo
Cada proceso tiene su propia porción de memoria asignada por el sistema operativo. De forma predeterminada, esa memoria no se puede compartir con otros procesos: su navegador no tiene acceso a la memoria asignada a su reproductor multimedia y viceversa. Lo mismo sucede si ejecuta dos instancias del mismo proceso, es decir, si inicia su navegador dos veces. (IPC). Cada proceso tiene un bloque de memoria asignado por el sistema operativo. De forma predeterminada, la memoria no se puede compartir con otros procesos: el navegador no puede acceder a la memoria asignada al reproductor multimedia y viceversa. Lo mismo sucede si ejecuta dos instancias del mismo proceso, es decir, inicia el navegador dos veces. El sistema operativo trata cada instancia como un proceso nuevo, asignando su propia porción independiente de memoria. Por lo tanto, de forma predeterminada, dos o más procesos no pueden compartir datos a menos que realicen un truco avanzado llamado comunicación entre procesos (IPC).A diferencia de los procesos, los subprocesos comparten la misma porción de memoria asignada a su proceso principal por el sistema operativo: el motor de audio puede acceder fácilmente a los datos en la interfaz principal del reproductor multimedia y viceversa. Por lo tanto, es más fácil que dos hilos se comuniquen entre sí. Además de eso, los subprocesos suelen ser más livianos que un proceso: requieren menos recursos y son más rápidos de crear, por eso también se les llama procesos livianos. A diferencia de los procesos, los subprocesos comparten el mismo bloque de memoria asignado por el sistema operativo al proceso principal: el motor de audio puede acceder fácilmente a los datos de la interfaz principal del reproductor multimedia, y viceversa. Por tanto, la conversación entre los dos hilos es más sencilla. Además de eso, los subprocesos son generalmente más livianos que los procesos: consumen menos recursos y son más rápidos de crear, por lo que también se les llama procesos livianos.
Los subprocesos son una forma práctica de hacer que su programa realice múltiples operaciones al mismo tiempo. Sin subprocesos, tendría que escribir un programa por tarea, ejecutarlos como procesos y sincronizarlos a través del sistema operativo. Esto sería más difícil (IPC es complicado) y más lento (los procesos son más pesados que los subprocesos). Los subprocesos son una forma conveniente para que un programa realice múltiples operaciones simultáneamente. Sin subprocesos, habría que escribir un programa para cada tarea, ejecutarlos como procesos y sincronizarlos a través del sistema operativo. Esto será más difícil (IPC es más complicado) y más lento (los procesos son más pesados que los subprocesos).
Hilos verdes, de fibras.
Fibra de hilo verde
Los subprocesos mencionados hasta ahora son una cuestión del sistema operativo: un proceso que quiere activar un nuevo subproceso tiene que hablar con el sistema operativo. Sin embargo, no todas las plataformas admiten subprocesos de forma nativa. Los hilos verdes, también conocidos como fibras, son un tipo de emulación que hace que los programas multiproceso funcionen en entornos que no ofrecen esa capacidad. Por ejemplo, una máquina virtual podría implementar subprocesos verdes en caso de que el sistema operativo subyacente no tenga soporte para subprocesos nativos. Los subprocesos mencionados hasta ahora son todos problemas del sistema operativo: un proceso que desee activar un nuevo subproceso debe comunicarse con el sistema operativo. Sin embargo, no todas las plataformas admiten subprocesos. Los hilos verdes, también conocidos como fibras, son una emulación que permite que programas multiproceso funcionen en entornos que no proporcionan esta funcionalidad. Por ejemplo, una máquina virtual podría implementar subprocesos verdes en caso de que el sistema operativo subyacente no admita subprocesos nativos.
Los hilos verdes son más rápidos de crear y administrar porque evitan por completo el sistema operativo, pero también tienen desventajas. Escribiré sobre ese tema en uno de los próximos episodios. Los hilos verdes son más rápidos de crear y administrar porque pasan por alto el sistema operativo por completo, pero tienen desventajas. Escribiré un artículo sobre este tema en el próximo episodio.
El nombre “hilos verdes” se refiere al Equipo Verde de Sun Microsystem que diseñó la biblioteca de hilos Java original en los años 90. Hoy en día, Java ya no utiliza subprocesos verdes: cambiaron a subprocesos nativos en el año 2000. Algunos otros lenguajes de programación (Go, Haskell o Rust, por nombrar algunos) implementan equivalentes de subprocesos verdes en lugar de nativos. El nombre “Green Threads” fue acuñado por el Green Team de Sun Microsystem, quien diseñó la biblioteca de subprocesos Java original en la década de 1990. Hoy en día, Java ya no usa subprocesos verdes: cambiaron a subprocesos nativos en el año 2000. Algunos otros lenguajes de programación (Go, Haskell o Rust, por nombrar algunos) implementan equivalentes de subprocesos verdes en lugar de subprocesos nativos.
Para qué se utilizan los hilos
¿Para qué se utilizan los hilos?
¿Por qué un proceso debería emplear múltiples subprocesos? Como mencioné antes, hacer las cosas en paralelo acelera mucho las cosas. Supongamos que está a punto de renderizar una película en su editor de películas. El editor podría ser lo suficientemente inteligente como para distribuir la operación de renderizado en múltiples subprocesos, donde cada subproceso procesa una parte de la película final. Entonces, si con un hilo la tarea tomaría, digamos, una hora, con dos hilos tomaría 30 minutos; con cuatro hilos 15 minutos, y así sucesivamente. ¿Por qué un proceso debería utilizar varios subprocesos? Como mencioné antes, el procesamiento paralelo puede acelerar las cosas significativamente. Digamos que desea renderizar una película en un editor de películas. El editor puede ser lo suficientemente inteligente como para distribuir las operaciones de renderizado en múltiples subprocesos, donde cada subproceso maneja una parte de la película final. Entonces, si una tarea toma una hora con un hilo, 30 minutos con dos hilos; 15 minutos con cuatro hilos, y así sucesivamente.
¿Es realmente así de simple? Hay tres puntos importantes a considerar: ¿Es realmente así de simple? Hay tres puntos a considerar:
Primero, no todos los programas necesitan ser multiproceso. Si su aplicación realiza operaciones secuenciales o espera con frecuencia a que el usuario haga algo, es posible que el subproceso múltiple no sea tan beneficioso; No todos los programas necesitan subprocesos múltiples. Si su aplicación realiza operaciones secuenciales o espera con frecuencia a que el usuario realice ciertas acciones, el subproceso múltiple puede no ser tan beneficioso;
-
simplemente no se lanzan más subprocesos a una aplicación para que se ejecute más rápido: cada subtarea debe pensarse y diseñarse cuidadosamente para realizar operaciones paralelas; No es necesario lanzar más subprocesos a la aplicación para que se ejecute más rápido: cada subtarea debe pensarse y diseñarse cuidadosamente para realizar operaciones paralelas;
-
No está 100% garantizado que los subprocesos realicen sus operaciones realmente en paralelo, es decir, al mismo tiempo: realmente depende del hardware subyacente. No existe una garantía del 100% de que los subprocesos realmente realicen sus operaciones en paralelo, es decir, al mismo tiempo: realmente depende del hardware subyacente.
El último es crucial: si tu ordenador no soporta múltiples operaciones al mismo tiempo, el sistema operativo tiene que simularlas. Veremos cómo en un minuto. Por ahora, pensemos en la concurrencia como la percepción de tener tareas que se ejecutan al mismo tiempo, mientras que el verdadero paralelismo son tareas que literalmente se ejecutan al mismo tiempo.
Este último punto es importante: si tu ordenador no puede soportar múltiples operaciones al mismo tiempo, el sistema operativo tiene que simularlas. Lo veremos en un momento. Ahora, pensemos en la concurrencia como la sensación de ejecutar tareas simultáneamente y en el verdadero paralelismo como tareas que se ejecutan simultáneamente.
2. El paralelismo es un subconjunto de la concurrencia. El paralelismo es un subconjunto de la concurrencia.
¿Qué hace posible la concurrencia y el paralelismo?
¿Qué hace posible la concurrencia y el paralelismo?
La unidad central de procesamiento (CPU) de su computadora hace el trabajo duro de ejecutar programas. Está formado por varias partes, siendo la principal el llamado núcleo: allí es donde realmente se realizan los cálculos. Un núcleo es capaz de ejecutar sólo una operación a la vez. La unidad central de procesamiento (CPU) de su computadora es responsable de ejecutar los programas. Consta de varias partes, siendo la principal el llamado núcleo: aquí es donde realmente se realizan los cálculos. Un núcleo sólo puede ejecutar una operación a la vez.
Por supuesto, esto es un gran inconveniente. Por esta razón, los sistemas operativos han desarrollado técnicas avanzadas para brindar al usuario la capacidad de ejecutar múltiples procesos (o subprocesos) a la vez, especialmente en entornos gráficos, incluso en una máquina de un solo núcleo. La más importante se llama multitarea preventiva, donde la prioridad es la capacidad de interrumpir una tarea, cambiar a otra y luego reanudar la primera tarea más adelante. Por supuesto, esto es un gran inconveniente. Por lo tanto, los sistemas operativos han desarrollado técnicas avanzadas que permiten a los usuarios ejecutar múltiples procesos (o subprocesos) simultáneamente, especialmente en entornos gráficos e incluso en máquinas de un solo núcleo. La más importante de ellas se llama multitarea preventiva, donde la prioridad es la capacidad de interrumpir una tarea, cambiar a otra y luego reanudar la primera tarea más adelante.
Entonces, si su CPU tiene un solo núcleo, parte del trabajo de un sistema operativo es distribuir esa potencia informática de un solo núcleo entre múltiples procesos o subprocesos, que se ejecutan uno tras otro en un bucle. Esta operación le da la ilusión de tener más de un programa ejecutándose en paralelo, o un solo programa haciendo varias cosas al mismo tiempo (si es multiproceso). Se cumple la simultaneidad, pero aún falta el verdadero paralelismo (la capacidad de ejecutar procesos simultáneamente). Entonces, si su CPU solo tiene un núcleo, parte del trabajo del sistema operativo es distribuir la potencia informática de un único núcleo entre múltiples procesos o subprocesos que se ejecutan uno tras otro en un bucle. Esta operación le da la ilusión de que hay varios programas ejecutándose en paralelo o que un programa está haciendo varias cosas al mismo tiempo (si tiene múltiples subprocesos). Si bien se satisface la concurrencia, todavía falta el verdadero paralelismo (la capacidad de ejecutar procesos simultáneamente).
Hoy en día, las CPU modernas tienen más de un núcleo bajo el capó, donde cada uno realiza una operación independiente a la vez. Esto significa que con dos o más núcleos es posible un verdadero paralelismo. Por ejemplo, mi Intel Core i7 tiene cuatro núcleos: puede ejecutar cuatro procesos o subprocesos diferentes al mismo tiempo, simultáneamente. Hoy en día, las CPU modernas tienen varios núcleos y cada uno realiza una operación independiente a la vez. Esto significa que es posible un verdadero paralelismo utilizando dos o más núcleos. Por ejemplo, mi Intel Core i7 tiene cuatro núcleos: puede ejecutar cuatro procesos o subprocesos diferentes simultáneamente.
Los sistemas operativos son capaces de detectar la cantidad de núcleos de CPU y asignar procesos o subprocesos a cada uno de ellos. Se puede asignar un subproceso a cualquier núcleo que desee el sistema operativo, y este tipo de programación es completamente transparente para el programa que se ejecuta. Además, la multitarea preventiva podría activarse en caso de que todos los núcleos estén ocupados. Esto le brinda la capacidad de ejecutar más procesos y subprocesos que el número real de núcleos disponibles en su máquina. El sistema operativo puede detectar la cantidad de núcleos de CPU y asignar un proceso o subproceso a cada núcleo de CPU. Se puede asignar un subproceso a cualquier núcleo que desee el sistema operativo y esta programación es completamente transparente para el programa en ejecución. Además, la multitarea preventiva puede entrar en juego cuando todos los núcleos están ocupados. Esto le permite ejecutar más procesos y subprocesos que el número real de núcleos disponibles en su computadora.
Aplicación multiproceso en un solo núcleo: ¿tiene sentido?
Aplicaciones multiproceso en un solo núcleo: ¿tiene sentido?
Es imposible lograr un verdadero paralelismo en una máquina de un solo núcleo. Sin embargo, todavía tiene sentido escribir un programa multiproceso, si su aplicación puede beneficiarse de él. Cuando un proceso emplea varios subprocesos, la multitarea preventiva puede mantener la aplicación en ejecución incluso si uno de esos subprocesos realiza una tarea lenta o bloqueadora. Es imposible lograr un verdadero paralelismo en una máquina de un solo núcleo. Sin embargo, todavía tiene sentido escribir programas multiproceso si su aplicación puede beneficiarse de ello. Cuando un proceso utiliza varios subprocesos, la multitarea preventiva puede mantener la aplicación en ejecución incluso si uno de los subprocesos realiza una tarea lenta o bloqueadora.
Digamos, por ejemplo, que está trabajando en una aplicación de escritorio que lee algunos datos de un disco muy lento. Si escribe el programa con un solo subproceso, toda la aplicación se congelará hasta que finalice la operación del disco: la potencia de la CPU asignada al único subproceso se desperdicia mientras se espera que el disco se active. Por supuesto, el sistema operativo está ejecutando muchos otros procesos además de este, pero su aplicación específica no progresará. Por ejemplo, está trabajando en una aplicación de escritorio que lee algunos datos de un disco muy lento. Si un programa se escribe utilizando un solo subproceso, toda la aplicación se congela hasta que se completa la operación del disco: la energía de la CPU asignada al único subproceso se desperdicia mientras se espera que el disco se active. Por supuesto, además de este proceso, el sistema operativo tiene muchos otros procesos en ejecución, pero su aplicación particular no progresará.Repensaremos su aplicación de forma multiproceso. El subproceso A es responsable del acceso al disco, mientras que el subproceso B se encarga de la interfaz principal. Si el subproceso A se atasca esperando porque el dispositivo es lento, el subproceso B aún puede ejecutar la interfaz principal, manteniendo el programa receptivo. Esto es posible porque, al tener dos subprocesos, el sistema operativo puede intercambiar los recursos de la CPU entre ellos sin quedarse atascado en el más lento. Repensemos su aplicación en términos de subprocesos múltiples. El subproceso A es responsable del acceso al disco, mientras que el subproceso B es responsable de la interfaz principal. Si el hilo A se queda atascado esperando porque el dispositivo es lento, el hilo B aún puede ejecutar la interfaz principal, manteniendo el programa respondiendo. Esto es posible porque hay dos subprocesos y el sistema operativo puede intercambiar recursos de CPU entre ellos sin quedarse atascado en el subproceso más lento.
Más hilos, más problemas
Cuantos más hilos, más problemas.
Como sabemos, los subprocesos comparten la misma porción de memoria de su proceso principal. Esto hace que sea extremadamente fácil para dos o más intercambiar datos dentro de la misma aplicación. Por ejemplo: un editor de películas puede contener una gran parte de la memoria compartida que contiene la línea de tiempo del vídeo. Esta memoria compartida es leída por varios subprocesos de trabajo designados para representar la película en un archivo. Todos ellos solo necesitan un identificador (por ejemplo, un puntero) a esa área de memoria para poder leer y enviar cuadros renderizados al disco. Sabemos que los subprocesos comparten el mismo bloque de memoria de su proceso principal. Esto hace que sea muy fácil para dos o más intercambiar datos dentro de la misma aplicación. Por ejemplo: un editor de películas podría poseer la mayor parte de la memoria compartida que contiene la línea de tiempo del vídeo. Esta memoria compartida es leída por varios subprocesos de trabajo, que están designados para representar películas en archivos. Todos ellos solo requieren un identificador (por ejemplo, un puntero) a un área de memoria para poder leer datos de esa área de memoria y enviar los fotogramas renderizados al disco.
Todo funciona sin problemas siempre que dos o más subprocesos lean desde la misma ubicación de memoria. Los problemas aparecen cuando al menos uno de ellos escribe en la memoria compartida, mientras otros leen de ella. En este punto pueden ocurrir dos problemas: Dos o más subprocesos que leen desde la misma ubicación de memoria pueden ejecutarse sin problemas. El problema surge cuando al menos una memoria escribe en la memoria compartida mientras otras leen de ella. Pueden surgir dos problemas en este momento:
-
carrera de datos: mientras un hilo de escritura modifica la memoria, es posible que un hilo de lectura esté leyendo de ella. Si el escritor aún no ha terminado su trabajo, el lector obtendrá datos corruptos; Carrera de datos: mientras el hilo de escritura modifica la memoria, el hilo de lectura puede estar leyendo la memoria. Si el autor no ha hecho su trabajo, el lector obtendrá datos corruptos;
-
condición de carrera: se supone que un hilo de lector debe leer solo después de que un escritor haya escrito. ¿Qué pasa si sucede lo contrario? Más sutil que una carrera de datos, una condición de carrera se trata de dos o más subprocesos que realizan su trabajo en un orden impredecible, cuando en realidad las operaciones deben realizarse en la secuencia adecuada para realizarse correctamente. Su programa puede desencadenar una condición de carrera incluso si ha sido protegido contra carreras de datos. Condición de carrera: el hilo de lectura solo debe leerse después de que el escritor haya escrito. ¿Qué pasa si sucede lo contrario? Más sutil que una carrera de datos, una condición de carrera es cuando dos o más subprocesos realizan su trabajo en un orden impredecible, cuando en realidad las operaciones deben realizarse en el orden correcto para funcionar correctamente. Su programa puede desencadenar una condición de carrera incluso si está protegido contra carreras de datos.
El concepto de seguridad de subprocesos.
El concepto de seguridad del hilo.
Se dice que un fragmento de código es seguro para subprocesos si funciona correctamente, es decir, sin carreras de datos ni condiciones de carrera, incluso si muchos subprocesos lo ejecutan simultáneamente. Es posible que haya notado que algunas bibliotecas de programación se declaran seguras para subprocesos: si está escribiendo un programa multiproceso, desea asegurarse de que cualquier otra función de terceros pueda usarse en diferentes subprocesos sin provocar problemas de concurrencia. Si un fragmento de código funciona correctamente, es decir, sin carreras de datos ni condiciones de carrera, entonces es seguro para subprocesos, incluso si muchos subprocesos lo ejecutan simultáneamente. Es posible que haya notado que algunas bibliotecas de programación se declaran seguras para subprocesos: si está escribiendo un programa de subprocesos múltiples, querrá asegurarse de que cualquier otra función de terceros se pueda utilizar en diferentes subprocesos sin causar problemas de concurrencia.
La causa fundamental de la carrera de datos
La causa fundamental de la competencia de datos
Sabemos que un núcleo de CPU sólo puede realizar una instrucción de máquina a la vez. Se dice que dicha instrucción es atómica porque es indivisible: no se puede dividir en operaciones más pequeñas. La palabra griega “átomo” (ἄτομος; atomos) significa incortable. Sabemos que un núcleo de CPU solo puede ejecutar una instrucción de máquina a la vez. Una instrucción de este tipo se denomina instrucción atómica porque es indivisible: no se puede dividir en operaciones más pequeñas. La palabra griega “átomo” (ἄτομος; atomos) significa todo.
La propiedad de ser indivisible hace que las operaciones atómicas sean seguras para subprocesos por naturaleza. Cuando un hilo realiza una escritura atómica en datos compartidos, ningún otro hilo puede leer la modificación a medio completar. Por el contrario, cuando un hilo realiza una lectura atómica de datos compartidos, lee el valor completo tal como apareció en un momento determinado. No hay forma de que un hilo se escape a través de una operación atómica, por lo que no puede ocurrir una carrera de datos. La naturaleza indivisible hace que las operaciones atómicas sean inherentemente seguras para subprocesos. Cuando un subproceso realiza una escritura atómica en datos compartidos, ningún otro subproceso puede leer las modificaciones a medio completar. Por el contrario, cuando un subproceso realiza una lectura atómica de datos compartidos, lee el valor completo que ocurre en algún momento. Los subprocesos no pueden funcionar de forma atómica, por lo que las carreras de datos no son posibles.La mala noticia es que la gran mayoría de las operaciones que existen son no atómicas. Incluso una asignación trivial como x = 1 en algún hardware podría estar compuesta por múltiples instrucciones de máquina atómicas, lo que hace que la asignación en sí misma no sea atómica en su conjunto. Entonces, se desencadena una carrera de datos si un hilo lee x mientras otro realiza la tarea. La mala noticia es que la gran mayoría de las operaciones no son atómicas. Incluso una asignación simple como x = 1 en algún hardware puede consistir en múltiples instrucciones de máquina atómica, lo que hace que la asignación en sí misma no sea atómica en su conjunto. Por lo tanto, si un hilo lee x mientras otro hilo realiza la asignación, se desencadenará una carrera de datos.
La causa fundamental de las condiciones de carrera.
Causa raíz de las condiciones de carrera
La multitarea preventiva le da al sistema operativo control total sobre la gestión de subprocesos: puede iniciar, detener y pausar subprocesos de acuerdo con algoritmos de programación avanzados. Usted, como programador, no puede controlar el tiempo ni el orden de ejecución. De hecho, no hay garantía de que un código simple como este: La multitarea preventiva le da al sistema operativo control total sobre la gestión de subprocesos: puede iniciar, detener y pausar subprocesos basándose en algoritmos de programación avanzados. Como programador, no tienes control sobre el tiempo ni el orden de ejecución. De hecho, no hay garantía de que un código tan simple:
writer_thread.start()
reader_thread.start ()
iniciaría los dos hilos en ese orden específico. Ejecute este programa varias veces y notará cómo se comporta de manera diferente en cada ejecución: a veces el hilo del escritor comienza primero, a veces lo hace el lector. Seguramente alcanzará una condición de carrera si su programa necesita que el escritor se ejecute siempre antes que el lector. Se iniciarán dos subprocesos en un orden específico. Ejecute este programa varias veces y notará cómo se comporta de manera diferente en cada ejecución: a veces el hilo de escritura comienza primero, a veces el hilo de lectura comienza primero. Si su programa requiere que los escritores siempre se ejecuten antes que los lectores, seguramente tendrá una condición de carrera.
Este comportamiento se llama no determinista: el resultado cambia cada vez y no se puede predecir. La depuración de programas afectados por una condición de carrera es muy molesta porque no siempre se puede reproducir el problema de forma controlada. Este comportamiento se llama no determinismo: el resultado cambia cada vez y no se puede predecir. Depurar un programa afectado por condiciones de carrera es muy molesto porque no siempre se puede reproducir el problema de forma controlada.
Enseñar a los hilos a llevarse bien: control de concurrencia
Enseñar hilos para llevarse bien: control de concurrencia
Tanto las carreras de datos como las condiciones de carrera son problemas del mundo real: algunas personas incluso murieron a causa de ellas. El arte de acomodar dos o más subprocesos simultáneos se llama control de concurrencia: los sistemas operativos y los lenguajes de programación ofrecen varias soluciones para solucionarlo. Los más importantes: Las carreras de datos y las condiciones de carrera son problemas del mundo real: algunas personas incluso han muerto a causa de ellas. El acto de acomodar dos o más subprocesos simultáneos se denomina control de concurrencia: los sistemas operativos y los lenguajes de programación proporcionan varias soluciones para manejarlo. Lo más importante es:
-
sincronización: una forma de garantizar que los recursos sean utilizados por un solo subproceso a la vez. La sincronización consiste en marcar partes específicas de su código como “protegidas” para que dos o más subprocesos simultáneos no lo ejecuten simultáneamente, arruinando sus datos compartidos; Sincronización: un método para garantizar que solo un subproceso utilice un recurso a la vez. La sincronización consiste en marcar una parte específica del código como “protegida” para que dos o más subprocesos concurrentes no puedan ejecutarla al mismo tiempo, corrompiendo así los datos compartidos;
-
operaciones atómicas: un conjunto de operaciones no atómicas (como la tarea mencionada anteriormente) se pueden convertir en atómicas gracias a instrucciones especiales proporcionadas por el sistema operativo. De esta manera, los datos compartidos siempre se mantienen en un estado válido, sin importar cómo accedan a ellos otros subprocesos; Operaciones atómicas: gracias a instrucciones especiales proporcionadas por el sistema operativo, muchas operaciones no atómicas (como la asignación mencionada anteriormente) se pueden convertir en operaciones atómicas. De esta manera, no importa cómo otros subprocesos accedan a los datos compartidos, los datos compartidos siempre permanecerán en un estado válido;
-
datos inmutables: los datos compartidos están marcados como inmutables, nada puede cambiarlos: los subprocesos solo pueden leerlos, eliminando la causa raíz. Como sabemos, los subprocesos pueden leer de forma segura desde la misma ubicación de memoria siempre que no la modifiquen. Esta es la filosofía principal detrás de la programación funcional. Datos inmutables: los datos compartidos están marcados como inmutables, nada puede cambiarlos: los subprocesos solo pueden leerlos, eliminando la causa raíz. Sabemos que los subprocesos pueden leer datos de forma segura desde la misma ubicación de memoria siempre que no los modifiquen. Este es el principio fundamental detrás de la programación funcional.
Cubriré todos estos temas fascinantes en los próximos episodios de esta miniserie sobre concurrencia. ¡Manténganse al tanto! En el próximo episodio de esta miniserie sobre concurrencia, analizaré todos estos fascinantes temas. ¡Estén atentos!
Texto original: https://www.internalpointers.com/post/gentle-introduction-multithreading
What to read next
Want more posts about Translation?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #Translation?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home