Articulo de referencia

condición de carrera

Condición de carrera en un circuito lógico. Aquí, ∆ t 1 y ∆ t 2 representan los retardos de propagación de los elementos lógicos. Cuando el valor de entrada A cambia de bajo a a...

Condición de carrera en un circuito lógico. Aquí, t 1 y t 2 representan los retardos de propagación de los elementos lógicos. Cuando el valor de entrada A cambia de bajo a alto, el circuito genera un pico corto de duración (∆ t 1 + ∆ t 2 ) − ∆ t 2 = ∆ t 1 .

Una condición de carrera o riesgo de carrera es una situación en la que el comportamiento sustancial de un sistema electrónico , de software u otro tipo depende de la secuencia o el momento de eventos incontrolables, lo que genera resultados inesperados o inconsistentes. Se convierte en un error cuando uno o más de los comportamientos posibles son indeseables.

El término condición de carrera se utilizaba ya en 1954, por ejemplo en la tesis doctoral de David A. Huffman titulada "La síntesis de circuitos de conmutación secuencial". [ 1 ]

Las condiciones de carrera pueden ocurrir especialmente en circuitos lógicos o en programas de software concurrentes o distribuidos . El uso de la exclusión mutua puede prevenir las condiciones de carrera.

En electrónica

Un ejemplo típico de condición de carrera puede ocurrir cuando una puerta lógica combina señales que han viajado por diferentes caminos desde la misma fuente. Las entradas de la puerta pueden cambiar en momentos ligeramente diferentes en respuesta a un cambio en la señal de origen. La salida puede, durante un breve período, cambiar a un estado no deseado antes de volver al estado previsto. Ciertos sistemas pueden tolerar tales fallos , pero si esta salida funciona como una señal de reloj para otros sistemas que contienen memoria, por ejemplo, el sistema puede desviarse rápidamente de su comportamiento previsto (en efecto, el fallo temporal se convierte en un fallo permanente).

Consideremos, por ejemplo, una puerta lógica AND de dos entradas alimentada con la siguiente lógica:producción=AA¯{\displaystyle {\text{salida}}=A\wedge {\overline {A}}}Una señal lógicaA{\displaystyle A}en una entrada y su negación booleanaA¯{\displaystyle {\bar {A}}} en otra entrada nunca puede, en teoría, producir un valor verdadero comoAA¯1{\displaystyle A\wedge {\overline {A}}\neq 1}. Sin embargo, si se producen cambios en el valor deA{\displaystyle A}tarda más tiempo en propagarse a la segunda entrada que a la primera cuandoA{\displaystyle A}cambia de falso a verdadero, luego se producirá un breve período durante el cual ambas entradas serán verdaderas, y por lo tanto la salida de la compuerta también será verdadera. [ 2 ]

Un ejemplo práctico de condición de carrera puede ocurrir cuando se utiliza un circuito lógico para detectar ciertas salidas de un contador. Si todos los bits del contador no cambian exactamente al mismo tiempo, habrá patrones intermedios que pueden provocar coincidencias falsas.

Formas críticas y no críticas

Se produce una condición de carrera crítica cuando el orden en que se modifican las variables internas determina el estado final en el que terminará la máquina de estados .

Se produce una condición de carrera no crítica cuando el orden en que se modifican las variables internas no determina el estado final en el que terminará la máquina de estados.

Formas estáticas, dinámicas y esenciales

Se produce una condición de carrera estática cuando se combinan una señal y su complemento.

Se produce una condición de carrera dinámica cuando se generan múltiples transiciones en lugar de una. Esto se debe a la interacción entre las compuertas. Se puede eliminar utilizando no más de dos niveles de compuertas.

Se produce una condición de carrera esencial cuando una señal de entrada tiene dos transiciones en menos del tiempo total de propagación de la retroalimentación. En ocasiones, se soluciona utilizando elementos de línea de retardo inductivos para aumentar eficazmente la duración de la señal de entrada.

Soluciones alternativas

Técnicas de diseño como los mapas de Karnaugh animan a los diseñadores a reconocer y eliminar las condiciones de carrera antes de que causen problemas. Al simplificar las expresiones booleanas y analizar las relaciones entre las variables de entrada, los diseñadores pueden reducir la probabilidad de cambios de señal no deseados que podrían provocar condiciones de carrera.

En muchos casos, se puede añadir redundancia lógica intencionadamente a los circuitos digitales para eliminar ciertos tipos de condiciones de carrera. Si bien la redundancia aumenta el número de puertas lógicas, puede estabilizar las transiciones de señal y prevenir fallos transitorios que se producen cuando las señales cambian en momentos ligeramente diferentes.

Los ingenieros también pueden aplicar métodos precisos de control de temporización y sincronización en circuitos secuenciales. Por ejemplo, el uso de elementos sincronizados, como los biestables, puede ayudar a garantizar que las señales cambien de forma predecible, reduciendo el riesgo de condiciones de carrera en sistemas digitales complejos.

A pesar de estas precauciones, algunos elementos lógicos aún pueden entrar en estados metaestables . En tales casos, un circuito permanece temporalmente en una condición inestable entre estados lógicos, lo que puede propagar señales inciertas a través del sistema y generar desafíos adicionales para los diseñadores de circuitos.

En software

En un programa informático, puede producirse una condición de carrera cuando varias rutas de código se ejecutan simultáneamente. Si estas rutas tardan más tiempo del esperado, pueden finalizar en un orden distinto, lo que puede provocar errores de software debido a un comportamiento inesperado. También puede darse una condición de carrera entre dos programas, lo que conlleva problemas de seguridad.

Las condiciones de carrera críticas provocan una ejecución inválida y errores de software , y suelen ocurrir cuando los procesos o subprocesos dependen de un estado compartido. Las operaciones sobre estados compartidos se realizan en secciones críticas que deben ser mutuamente excluyentes . El incumplimiento de esta regla puede corromper el estado compartido.

Una condición de carrera de datos es un tipo de condición de carrera. Las condiciones de carrera de datos son partes importantes de varios modelos formales de memoria . El modelo de memoria definido en los estándares C11 y C++11 especifica que un programa C o C++ que contiene una condición de carrera de datos tiene un comportamiento indefinido . [ 3 ] [ 4 ]

Una condición de carrera puede ser difícil de reproducir y depurar, ya que el resultado no es determinista y depende de la sincronización relativa entre los hilos que interfieren. Por lo tanto, los problemas de esta naturaleza pueden desaparecer al ejecutar en modo de depuración, agregar registros adicionales o conectar un depurador. Un error que desaparece de esta manera durante los intentos de depuración se suele denominar " error Heisen" . Por consiguiente, es mejor evitar las condiciones de carrera mediante un diseño de software cuidadoso.

Ejemplo

Supongamos que dos hilos incrementan cada uno en 1 el valor de una variable entera global. Idealmente, se produciría la siguiente secuencia de operaciones:

En el caso mostrado anteriormente, el valor final es 2, como se esperaba. Sin embargo, si los dos hilos se ejecutan simultáneamente sin bloqueo ni sincronización (mediante semáforos ), el resultado de la operación podría ser incorrecto. La siguiente secuencia alternativa de operaciones ilustra este escenario:

En este caso, el valor final es 1 en lugar del resultado esperado de 2. Esto se debe a que las operaciones de incremento no son mutuamente excluyentes. Las operaciones mutuamente excluyentes son aquellas que no pueden interrumpirse al acceder a algún recurso, como una ubicación de memoria.

carrera de datos

No todos consideran las carreras de datos como un subconjunto de las condiciones de carrera. [ 5 ] La definición precisa de carrera de datos es específica del modelo de concurrencia formal que se utilice, pero normalmente se refiere a una situación en la que una operación de memoria en un hilo podría potencialmente intentar acceder a una ubicación de memoria al mismo tiempo que una operación de memoria en otro hilo está escribiendo en esa ubicación de memoria, en un contexto donde esto es peligroso. Esto implica que una carrera de datos es diferente de una condición de carrera ya que es posible tener no determinismo debido al tiempo incluso en un programa sin carreras de datos, por ejemplo, en un programa en el que todos los accesos a memoria utilizan solo operaciones atómicas .

Esto puede ser peligroso porque, en muchas plataformas, si dos hilos escriben en una ubicación de memoria al mismo tiempo, es posible que dicha ubicación contenga un valor que sea una combinación arbitraria y sin sentido de los bits que representan los valores que cada hilo intentaba escribir; esto podría provocar una corrupción de memoria si el valor resultante es uno que ninguno de los hilos intentó escribir (a veces se denomina " escritura incompleta "). Del mismo modo, si un hilo lee de una ubicación mientras otro hilo escribe en ella, es posible que la lectura devuelva un valor que sea una combinación arbitraria y sin sentido de los bits que representan el valor que contenía la ubicación de memoria antes de la escritura y de los bits que representan el valor que se está escribiendo.

En muchas plataformas, se proporcionan operaciones de memoria especiales para el acceso simultáneo; en estos casos, el acceso simultáneo mediante estas operaciones especiales suele ser seguro, pero el acceso simultáneo mediante otras operaciones de memoria es peligroso. A veces, estas operaciones especiales (que son seguras para el acceso simultáneo) se denominan operaciones atómicas o de sincronización , mientras que las operaciones ordinarias (que no son seguras para el acceso simultáneo) se denominan operaciones de datos . Probablemente por eso se habla de condiciones de carrera; en muchas plataformas, donde existe una condición de carrera que involucra solo operaciones de sincronización , dicha condición puede ser no determinista pero segura; sin embargo, una condición de carrera podría provocar corrupción de memoria o un comportamiento indefinido.

Ejemplos de definiciones de condiciones de carrera en modelos de concurrencia específicos

La definición precisa de condición de carrera varía según los modelos formales de concurrencia. Esto es importante porque el comportamiento concurrente suele ser poco intuitivo, por lo que a veces se recurre al razonamiento formal.

El estándar C++ , en el borrador N4296 (19-11-2014), define la condición de carrera de datos de la siguiente manera en la sección 1.10.23 (página 14) [ 6 ]

Dos acciones son potencialmente concurrentes si

  • son ejecutados por diferentes hilos, o
  • No están secuenciadas y al menos una de ellas es ejecutada por un manejador de señales.

La ejecución de un programa presenta una condición de carrera si contiene dos acciones potencialmente concurrentes y conflictivas, al menos una de las cuales no es atómica, y ninguna ocurre antes que la otra, salvo en el caso especial de los manejadores de señales que se describe a continuación [omitido]. Cualquier condición de carrera de este tipo da como resultado un comportamiento indefinido.

Las partes de esta definición relacionadas con los manejadores de señales son idiosincrásicas de C++ y no son típicas de las definiciones de condiciones de carrera .

El artículo Detección de condiciones de carrera en sistemas de memoria débil [ 7 ] proporciona una definición diferente:

Dos operaciones de memoria entran en conflicto si acceden a la misma ubicación y al menos una de ellas es una operación de escritura  ... Dos operaciones de memoria, x e y, en una ejecución secuencialmente consistente forman una carrera〈x,y〉, si y solo si x e y entran en conflicto y no están ordenadas por la relación hb1 de la ejecución. La carrera 〈x,y〉 es una carrera de datos si y solo si al menos una de x o y es una operación de datos.

Aquí tenemos dos operaciones de memoria que acceden a la misma ubicación, una de las cuales es una escritura.

La relación hb1 se define en otra parte del artículo y es un ejemplo de una relación típica de precedencia . Intuitivamente, si podemos demostrar que nos encontramos en una situación en la que se garantiza que una operación de memoria X se ejecutará por completo antes de que comience otra operación de memoria Y, decimos que "X precede a Y". Si ni "X precede a Y" ni "Y precede a X", decimos que X e Y "no están ordenadas por la relación hb1". Por lo tanto, la cláusula "...  y no están ordenadas por la relación hb1 de ejecución" puede traducirse intuitivamente como "...  y X e Y son potencialmente concurrentes".

El artículo considera peligrosas únicamente aquellas situaciones en las que al menos una de las operaciones de memoria es una operación de datos ; en otras partes de este artículo, también se define una clase de operaciones de sincronización que son seguras para un uso potencialmente simultáneo, a diferencia de las operaciones de datos .

La especificación del lenguaje Java [ 8 ] proporciona una definición diferente:

Se dice que dos accesos a la misma variable (lecturas o escrituras) son conflictivos si al menos uno de los accesos es una escritura  ... Cuando un programa contiene dos accesos conflictivos (§17.4.1) que no están ordenados por una relación de precedencia, se dice que contiene una condición de carrera  ... una condición de carrera no puede causar un comportamiento incorrecto, como devolver una longitud incorrecta para una matriz.

Una diferencia crítica entre el enfoque de C++ y el enfoque de Java es que en C++, una carrera de datos es un comportamiento indefinido, mientras que en Java, una carrera de datos simplemente afecta las acciones entre subprocesos . [ 8 ] Esto significa que en C++, un intento de ejecutar un programa que contiene una carrera de datos podría (aunque se adhiera a la especificación) fallar o podría exhibir un comportamiento inseguro o extraño, mientras que en Java, un intento de ejecutar un programa que contiene una carrera de datos puede producir un comportamiento de concurrencia no deseado, pero por lo demás (suponiendo que la implementación se adhiera a la especificación) es seguro.

Consistencia secuencial para la libertad de condiciones de carrera de datos

Un aspecto importante de las condiciones de carrera es que, en algunos contextos, un programa libre de condiciones de carrera tiene garantizada su ejecución de forma secuencialmente consistente , lo que facilita enormemente el razonamiento sobre el comportamiento concurrente del programa. Se dice que los modelos formales de memoria que proporcionan dicha garantía exhiben una propiedad SC para DRF ( consistencia secuencial para la ausencia de condiciones de carrera ). Se ha afirmado que este enfoque ha alcanzado un consenso reciente (presumiblemente en comparación con enfoques que garantizan la consistencia secuencial en todos los casos, o con enfoques que no la garantizan en absoluto). [ 9 ]

Por ejemplo, en Java, esta garantía se especifica directamente: [ 8 ]

Un programa está correctamente sincronizado si y solo si todas las ejecuciones secuencialmente consistentes están libres de condiciones de carrera.

Si un programa está correctamente sincronizado, entonces todas las ejecuciones del programa parecerán ser secuencialmente consistentes (§17.4.3).

Esta es una garantía sumamente sólida para los programadores. No necesitan razonar sobre reordenamientos para determinar si su código contiene condiciones de carrera. Por lo tanto, tampoco necesitan razonar sobre reordenamientos al determinar si su código está correctamente sincronizado. Una vez que se determina que el código está correctamente sincronizado, el programador no tiene que preocuparse de que los reordenamientos afecten su código.

Un programa debe estar correctamente sincronizado para evitar comportamientos contraintuitivos que pueden surgir al reordenar el código. Si bien una sincronización correcta no garantiza que el comportamiento general del programa sea correcto, sí permite al programador razonar sobre sus posibles comportamientos de forma sencilla. El comportamiento de un programa correctamente sincronizado depende mucho menos de posibles reordenamientos. Sin una sincronización adecuada, pueden producirse comportamientos muy extraños, confusos y contraintuitivos.

Por el contrario, un borrador de especificación de C++ no requiere directamente un SC para la propiedad DRF, sino que simplemente observa que existe un teorema que lo proporciona:

[Nota: Se puede demostrar que los programas que utilizan correctamente los mutex y las operaciones memory_order_seq_cst para evitar todas las condiciones de carrera y no utilizan otras operaciones de sincronización se comportan como si las operaciones ejecutadas por sus hilos constituyentes estuvieran simplemente intercaladas, y cada cálculo de valor de un objeto se toma del último efecto secundario sobre ese objeto en dicha intercalación. Esto se conoce normalmente como "consistencia secuencial". Sin embargo, esto solo se aplica a programas libres de condiciones de carrera, y estos programas no pueden observar la mayoría de las transformaciones de programas que no modifican la semántica de los programas de un solo hilo. De hecho, la mayoría de las transformaciones de programas de un solo hilo siguen estando permitidas, ya que cualquier programa que se comporte de manera diferente como resultado debe realizar una operación indefinida.— fin de la nota

Cabe señalar que el borrador de la especificación de C++ admite la posibilidad de programas válidos que utilicen operaciones de sincronización con un `memory_order` distinto de `memory_order_seq_cst`. En tal caso, el resultado puede ser un programa correcto, pero sin garantía de consistencia secuencial. En otras palabras, en C++, algunos programas correctos no son secuencialmente consistentes. Se considera que este enfoque permite a los programadores de C++ optar por una ejecución más rápida del programa a costa de sacrificar la facilidad de razonamiento sobre el mismo. [ 9 ]

Existen diversos teoremas, a menudo presentados en forma de modelos de memoria, que proporcionan garantías de coherencia secuencial para DRF en distintos contextos. Las premisas de estos teoremas suelen imponer restricciones tanto al modelo de memoria (y, por lo tanto, a la implementación) como al programador; es decir, normalmente existen programas que no cumplen las premisas del teorema y cuya ejecución no puede garantizarse de forma secuencialmente consistente.

El modelo de memoria DRF1 [ 10 ] proporciona SC para DRF y permite las optimizaciones de los modelos de memoria WO (ordenamiento débil), RCsc ( consistencia de liberación con operaciones especiales secuencialmente consistentes), VAX y data-race-free-0. El modelo de memoria PLpc [ 11 ] proporciona SC para DRF y permite las optimizaciones de los modelos TSO ( orden de almacenamiento total ), PSO, PC ( consistencia del procesador ) y RCpc (consistencia de liberación con operaciones especiales de consistencia del procesador). DRFrlx [ 12 ] proporciona un esbozo de un teorema SC para DRF en presencia de atómicos relajados.

Seguridad informática

Muchas condiciones de carrera de software tienen implicaciones asociadas para la seguridad informática . Una condición de carrera permite que un atacante con acceso a un recurso compartido provoque el mal funcionamiento de otros actores que utilizan ese recurso, lo que resulta en efectos como la denegación de servicio [ 13 ] y la escalada de privilegios . [ 14 ] [ 15 ]

Un tipo específico de condición de carrera implica verificar un predicado (por ejemplo, para la autenticación ) y luego actuar sobre dicho predicado, mientras que el estado puede cambiar entre el momento de la verificación y el momento de su uso . Cuando este tipo de error existe en código sensible a la seguridad, se crea una vulnerabilidad de seguridad denominada error de tiempo de verificación a tiempo de uso ( TOCTTOU ).

Las condiciones de carrera también se utilizan intencionalmente para crear generadores de números aleatorios de hardware y funciones físicamente inclonables . [ 16 ] Las PUF se pueden crear diseñando topologías de circuitos con rutas idénticas a un nodo y confiando en las variaciones de fabricación para determinar aleatoriamente qué rutas se completarán primero. [ 17 ] Al medir el conjunto específico de resultados de las condiciones de carrera de cada circuito fabricado, se puede recopilar un perfil para cada circuito y mantenerlo en secreto para verificar posteriormente la identidad de un circuito.

Sistemas de archivos

Dos o más programas pueden entrar en conflicto al intentar modificar o acceder a un sistema de archivos, lo que puede provocar corrupción de datos o escalada de privilegios. [ 14 ] El bloqueo de archivos es una solución común. Un método más complejo consiste en organizar el sistema de forma que un único proceso (un demonio o similar) tenga acceso exclusivo al archivo, y todos los demás procesos que necesiten acceder a los datos de ese archivo lo hagan únicamente mediante comunicación entre procesos con dicho proceso. Esto requiere sincronización a nivel de proceso.

Existe una forma diferente de condición de carrera en los sistemas de archivos donde programas no relacionados pueden afectarse entre sí al consumir repentinamente recursos disponibles como espacio en disco, espacio de memoria o ciclos de procesador. El software que no esté cuidadosamente diseñado para anticipar y manejar esta situación de carrera puede volverse impredecible. Este riesgo puede pasarse por alto durante mucho tiempo en un sistema que parece muy confiable. Pero eventualmente, se pueden acumular suficientes datos o agregar suficiente software adicional para desestabilizar críticamente muchas partes de un sistema. Un ejemplo de esto ocurrió con la casi pérdida del rover marciano "Spirit" poco después del aterrizaje, que ocurrió debido a entradas de archivos eliminadas que hicieron que la biblioteca del sistema de archivos consumiera todo el espacio de memoria disponible. [ 18 ] Una solución es que el software solicite y reserve todos los recursos que necesitará antes de comenzar una tarea; si esta solicitud falla, la tarea se pospone, evitando los muchos puntos donde podría haber ocurrido la falla. Alternativamente, cada uno de esos puntos puede estar equipado con manejo de errores, o el éxito de toda la tarea puede verificarse después, antes de continuar. Un enfoque más común es simplemente verificar que haya suficientes recursos del sistema disponibles antes de comenzar una tarea; Sin embargo, esto puede no ser suficiente, ya que en sistemas complejos las acciones de otros programas en ejecución pueden ser impredecibles.

Redes de contactos

En redes, consideremos una red de chat distribuida como IRC , donde un usuario que inicia un canal adquiere automáticamente privilegios de operador. Si dos usuarios en servidores diferentes, en extremos opuestos de la misma red, intentan iniciar un canal con el mismo nombre simultáneamente, el servidor de cada usuario les otorgará privilegios de operador, ya que ninguno habrá recibido aún la señal del otro servidor indicando que ha asignado dicho canal. (Este problema se ha resuelto en gran medida gracias a diversas implementaciones de servidores IRC).

En este caso de condición de carrera, el concepto de recurso compartido abarca el estado de la red (qué canales existen, qué usuarios los iniciaron y, por lo tanto, qué privilegios tienen), que cada servidor puede modificar libremente siempre que notifique a los demás servidores de la red sobre los cambios para que puedan actualizar su concepción del estado de la red. Sin embargo, la latencia en la red posibilita el tipo de condición de carrera descrita. En este caso, evitar las condiciones de carrera imponiendo algún tipo de control sobre el acceso al recurso compartido —por ejemplo, designando a un servidor para controlar quién tiene qué privilegios— implicaría convertir la red distribuida en una centralizada (al menos para esa parte de la operación de la red).

También pueden existir condiciones de carrera cuando un programa informático se escribe con sockets no bloqueantes , en cuyo caso el rendimiento del programa puede depender de la velocidad del enlace de red.

Sistemas de vital importancia

Los fallos de software en sistemas críticos para la vida pueden ser desastrosos. Las condiciones de carrera fueron uno de los fallos en la máquina de radioterapia Therac-25 , que provocó la muerte de al menos tres pacientes y lesiones a varios más. [ 19 ]

Otro ejemplo es el sistema de gestión de energía proporcionado por GE Energy y utilizado por FirstEnergy Corp., con sede en Ohio (entre otras centrales eléctricas). Existía una condición de carrera en el subsistema de alarmas; cuando tres líneas eléctricas caídas se desconectaban simultáneamente, la condición impedía que se enviaran alertas a los técnicos de monitoreo, lo que retrasaba su conocimiento del problema. Este fallo de software finalmente provocó el apagón de Norteamérica de 2003. [ 20 ] Posteriormente , GE Energy desarrolló un parche de software para corregir el error previamente desconocido.

Herramientas

Existen numerosas herramientas de software para detectar condiciones de carrera en el software. Estas se pueden clasificar en dos grandes grupos: herramientas de análisis estático y herramientas de análisis dinámico .

Thread Safety Analysis es una herramienta de análisis estático para el análisis estático intraprocedimental basado en anotaciones, originalmente implementada como una rama de gcc y ahora reimplementada en Clang , compatible con PThreads. [ 21 ]

Las herramientas de análisis dinámico incluyen:

  • Intel Inspector , una herramienta de comprobación y depuración de memoria e hilos para aumentar la fiabilidad, la seguridad y la precisión de las aplicaciones C/C++ y Fortran; Intel Advisor , una herramienta de asistencia para la optimización de la vectorización SIMD basada en muestreo y la gestión de hilos de memoria compartida para desarrolladores y arquitectos de software C, C++, C# y Fortran;
  • ThreadSanitizer, que utiliza instrumentación binaria ( basada en Valgrind ) o de código fuente, basada en LLVM , y admite PThreads; [ 22 ] y Helgrind, una herramienta Valgrind para detectar errores de sincronización en programas C, C++ y Fortran que utilizan las primitivas de subprocesos POSIX pthreads. [ 23 ]
  • El detector de carreras de datos [ 24 ] está diseñado para encontrar carreras de datos en el lenguaje de programación Go.

Existen varios puntos de referencia diseñados para evaluar la eficacia de las herramientas de detección de condiciones de carrera.

  • DataRaceBench [ 25 ] es un conjunto de pruebas de rendimiento diseñado para evaluar sistemática y cuantitativamente las herramientas de detección de condiciones de carrera de datos que analizan aplicaciones multihilo escritas en OpenMP .

En otras áreas

Las condiciones de carrera son una preocupación común en el diseño de interacción persona-ordenador y la usabilidad del software . Las interfaces hombre-máquina diseñadas intuitivamente requieren que el usuario reciba retroalimentación sobre sus acciones que se ajuste a sus expectativas, pero las acciones generadas por el sistema pueden interrumpir la acción o el flujo de trabajo actual del usuario de maneras inesperadas, como contestar o rechazar inadvertidamente una llamada entrante en un teléfono inteligente mientras se realiza una tarea diferente.

En la señalización ferroviaria del Reino Unido , la aplicación de la Regla 55 implicaba una situación de carrera . Según esta regla, si un tren se detenía en una vía en marcha debido a una señal, el fogonero de la locomotora debía dirigirse a la cabina de señales para avisar al señalero de la presencia del tren. En al menos un caso, ocurrido en Winwick en 1934, se produjo un accidente porque el señalero aceptó otro tren antes de que llegara el fogonero. Los sistemas de señalización modernos eliminan esta situación de carrera, ya que permiten al maquinista contactar instantáneamente con la cabina de señales por radio.

Las condiciones de carrera no se limitan a los sistemas digitales. La neurociencia está demostrando que también pueden darse en el cerebro de los mamíferos. Un ejemplo de carrera demostrada se da entre las vías neuronales que ejecutan un movimiento planificado y las vías separadas que pueden cancelar dicho movimiento. [ 26 ] [ 27 ]

Véase también

Referencias

  1. Huffman, David A. " La síntesis de circuitos de conmutación secuenciales. " (1954).
  2. Unger, SH (junio de 1995). "Riesgos, condiciones críticas de carrera y metaestabilidad" . IEEE Transactions on Computers . 44 (6): 754– 768. doi : 10.1109/12.391185 .
  3. "ISO/IEC 9899:2011 - Tecnología de la información - Lenguajes de programación - C" . Iso.org . Consultado el 30 de enero de 2018 .
  4. "ISO/IEC 14882:2011" . ISO. 2 de septiembre de 2011. Consultado el 3 de septiembre de 2011 .
  5. Regehr, John (2011-03-13). "Condición de carrera vs. Carrera de datos" . Embedded in Academia .
  6. "Borrador de trabajo, estándar para el lenguaje de programación C++" (PDF) . 19 de noviembre de 2014.
  7. Adve, Sarita & Hill, Mark & ​​Miller, Barton & HB Netzer, Robert. (1991). Detección de condiciones de carrera en sistemas de memoria débil . ACM SIGARCH Computer Architecture News. 19. 234–243. 10.1109/ISCA.1991.1021616.
  8. 1 2 3 "Capítulo 17. Hilos y bloqueos" . docs.oracle.com .
  9. 1 2 Adve, Sarita V.; Boehm, Hans-J. (2010). "Semántica de variables compartidas y sincronización (también conocidas como modelos de memoria)" (PDF) .
  10. Adve, Sarita (diciembre de 1993). Diseño de modelos de consistencia de memoria para multiprocesadores de memoria compartida (PDF) (tesis doctoral). Archivado (PDF) del original el 9 de diciembre de 2021. Consultado el 9 de diciembre de 2021 .
  11. Kourosh Gharachorloo y Sarita V. Adve y Anoop Gupta y John L. Hennessy y Mark D. Hill, Programación para diferentes modelos de consistencia de memoria , Journal of Parallel and Distributed Computing, 1992, volumen 15, páginas 399–407.
  12. Sinclair, Matthew David (2017). "Capítulo 3: Soporte y evaluación eficientes de átomos relajados" (PDF) . Coherencia y consistencia eficientes para jerarquías de memoria especializadas (doctorado). Universidad de Illinois en Urbana-Champaign.
  13. "CVE-2015-8461: Una condición de carrera al manejar errores de socket puede provocar un fallo de aserción en resolver.c" . Internet Systems Consortium . Archivado del original el 9 de junio de 2016. Recuperado el 5 de junio de 2017 .
  14. 1 2 "Vulnerabilidad en rmtree() y remove_tree(): CVE-2017-6512" . CPAN . Consultado el 5 de junio de 2017 .
  15. "Seguridad: condición de carrera *muy grande* en la caché de estadísticas si se almacena en caché cuando follow_symlink está deshabilitado" . lighttpd . Consultado el 5 de junio de 2017 .
  16. Colesa, Adrian; Tudoran, Radu; Banescu, Sebastian (2008). «Generación de números aleatorios por software basada en condiciones de carrera». 2008 10.º Simposio Internacional sobre Algoritmos Simbólicos y Numéricos para la Computación Científica . pp. 439–444 . doi : 10.1109/synasc.2008.36 . ISBN  978-0-7695-3523-4. S2CID 1586029 . 
  17. Bauer, Todd; Hamlet, Jason (noviembre de 2014). "Funciones físicas inclonables: una introducción" . IEEE Security & Privacy . 12 (6): 97–101 . doi : 10.1109/MSP.2014.123 . ISSN 1558-4046 . 
  18. Reeves, Glenn E.; Neilson, Tracy (2005). La anomalía FLASH del rover Spirit de Marte (PDF) . Conferencia Aeroespacial IEEE de 2005. IEEE. págs. 4186–4199 . doi : 10.1109/aero.2005.1559723 . ISBN  0-7803-8870-4ISSN 1095-323X 
  19. Leveson, Nancy; Turner, Clark S. "Una investigación de los accidentes del Therac-25 – I" . Courses.cs.vt.edu. Archivado del original el 15 de diciembre de 2017.
  20. Poulsen, Kevin (2004-04-07). "Rastreando el error del apagón" . SecurityFocus . Recuperado el 19 de septiembre de 2011 .
  21. "Análisis de seguridad de hilos – Documentación de Clang 10" . clang.llvm.org .
  22. "ThreadSanitizer – Documentación de Clang 10" . clang.llvm.org .
  23. "Helgrind: un detector de errores de hilos" . Valgrind .
  24. «Detector de carrera de datos» . Golang .
  25. "Conjunto de pruebas de rendimiento para condiciones de carrera" . 25 de julio de 2019 vía GitHub.
  26. "Cómo los cerebros se apresuran a cancelar movimientos erráticos" . Neuroskeptic . Discover Magazine. 3 de agosto de 2013. Archivado del original el 6 de agosto de 2013. Consultado el 7 de agosto de 2013 .
  27. Schmidt, Robert; Leventhal, Daniel K; Mallet, Nicolas; Chen, Fujun; Berke, Joshua D (2013). " Cancelar acciones implica una carrera entre vías de los ganglios basales" . Nature Neuroscience . 16 (8): 1118– 24. doi : 10.1038/nn.3456 . PMC 3733500. PMID 23852117 .  
  • Karam, GM; Buhr, RJA (agosto de 1990). "Analizadores de inanición y de condiciones críticas de carrera para Ada". IEEE Transactions on Software Engineering . 16 (8): 829– 843. doi : 10.1109/32.57622 .
  • Fuhrer, RM; Lin, B.; Nowick, SM (marzo de 1995). «Algoritmos para la asignación óptima de estados de máquinas de estados asíncronas». Investigación avanzada en VLSI, 1995. Actas de la 16.ª Conferencia sobre VLSI. pp. 59–75 . doi : 10.1109/ARVLSI.1995.515611 . ISBN  978-0-8186-7047-3. S2CID 4435912 . Como PDF archivado el 10/06/2021 en Wayback Machine
  • Artículo " Un nuevo marco para resolver el problema de asignación de estados para especificaciones basadas en eventos " por Luciano Lavagno, Cho W. Moon, Robert K. Brayton y Alberto Sangiovanni-Vincentelli.
  • Wheeler, David A. (7 de octubre de 2004). "Programador seguro: evite condiciones de carrera: la contención de recursos puede usarse en su contra" . IBM developerWorks . Archivado del original (PDF) el 1 de febrero de 2009.URL alternativa
  • Capítulo " Evitar condiciones de carrera " Archivado el 9 de marzo de 2014 en Wayback Machine (Programación segura para Linux y Unix HOWTO)
  • Condiciones de carrera, seguridad e inmutabilidad en Java , con código fuente de ejemplo y comparación con código C, por Chiral Software.
  • Karpov, Andrey (6 de abril de 2009). "Entrevista con Dmitriy Vyukov, autor de Relacy Race Detector (RRD)" .
  • Descripción del soporte de Microsoft
  • Condición de carrera frente a carrera de datos