concurrency - seccion - race condition vulnerability
Explicar las condiciones de carrera a una audiencia no técnica (18)
Recientemente, me encontré teniendo que escribir algunas preocupaciones que tengo sobre las condiciones de carrera en una aplicación que está en desarrollo (no yo). Es probable que esto llame la atención de las partes interesadas que no son técnicas y con las que no tengo una línea de comunicación directa, por lo que mi explicación debe estar en forma escrita.
Ya he intentado este artículo. Paso por alto las especificaciones técnicas lo mejor que puedo, doy un ejemplo de cómo ocurriría una condición de carrera en la aplicación y describo su impacto. Siento que lo hice bastante bien, pero está lejos de ser perfecto.
El problema es que, aunque trato de proteger al lector de la informática, todavía me resulta difícil eliminar frases como "hilos de ejecución" y "exclusión mutua" sin perder la corrección y la sustancia. El riesgo es que, con demasiada agitación manual, estas preocupaciones podrían descartarse como un boogeyman inventado.
De todos modos, mi pregunta para ti es esta: ¿ cómo explicarías las condiciones de carrera a una audiencia no técnica? ¿Te atreverías a explicar la programación de la CPU? ¿Invocarías a los filósofos que comen ?
No tienes que trabajar dentro de las limitaciones de mi situación (pero sería tremendamente útil si lo hicieras).
¿Qué tal el simple obvio?
Una condición de carrera es literalmente una carrera entre dos personas.
Una empresa está pujando por un proyecto. Dos empleados que trabajan independientemente en las ofertas los envían al cliente, pero uno de los empleados tiene información obsoleta. Ninguno de los empleados sabe que el otro está en el proceso de presentar una oferta, por lo tanto, dependiendo de quién sea más rápido, la primera oferta puede ser reemplazada por la del empleado más lento. Esto causará confusión ya que la oferta puede haber cambiado con el tiempo.
Debe haber comunicación entre los dos empleados para trabajar juntos o detener a uno de ellos.
Creo que es difícil explicar esto de una manera simple, porque pensar en la concurrencia es intrínsecamente difícil. La idea básica de una transacción financiera podría ser un buen lugar para comenzar, ya que las personas tendrán cierta familiaridad con ellos de la vida real.
En cualquier tipo de transacción, debe realizar entradas simultáneas en dos lugares: débitos y créditos. Si la transacción se interrumpe en el medio por otra persona que intenta realizar otra transacción, verá el saldo incorrecto en una u otra de las cuentas.
Creo que las transacciones bancarias pueden ser un buen ejemplo, tanto porque es fácil ver que un resultado incorrecto es malo como porque las condiciones de carrera son fáciles de crear en un entorno así.
Tengo $ 500 en mi cuenta. Alguien me transfiere $ 200 al mismo tiempo que retiro $ 50.
Ahora, si el banco no maneja las condiciones de carrera correctamente, harán lo siguiente (suponiendo que las transacciones se manejen manualmente, por supuesto). El empleado A verá la solicitud de agregar $ 200 a mi saldo, y tenga en cuenta que mi saldo actualmente es de $ 500. . El empleado B verá la solicitud de restar $ 50 de mi saldo, y tenga en cuenta que mi saldo es actualmente de $ 500 (el empleado A aún no ha transferido el dinero).
Clerk A finaliza la documentación y establece el saldo de mi cuenta en $ 700 (500 + los 200 que se suponía que debía agregar). Y luego, un minuto más tarde (porque el empleado B solo tuvo que tomar una taza de café), el empleado B termina la otra transacción y establece mi saldo en $ 450 (los 500 que tenía cuando revisó, menos los 50 que tenía la intención de restar )
Mi saldo ahora es de $ 450, cuando debería haber sido de $ 650, debido a una condición de carrera. El resultado depende del orden en que se realizaron las diferentes partes de las dos transacciones.
Esa es la descripción general de cómo las condiciones de carrera son malas. Ahora diga que en lugar de empleados, nuestra aplicación procesa dos tareas separadas al mismo tiempo (esos son sus ''hilos de ejecución''), y al igual que arriba, ambos leen un valor, modifican el valor que leen y luego escriben vuelve. Una de las modificaciones puede perderse si sucede en el orden que se muestra arriba. Eso debería relacionarlo con los problemas específicos de tu aplicación.
Hay un gran ejemplo en la Programación Simultánea Estructurada con Aplicaciones de Sistemas Operativos (según recuerdo)
En el empobrecido país de Bezerkistan, dos líneas se funden en una sola pista en un túnel. Hubo colisiones y la junta de gobierno necesita una solución.
El problema es que es montañoso y los ingenieros son ciegos. Hay muy poca advertencia anticipada de dos trenes a punto de colisionar en el túnel.
Este es el plan.
Pon un tazón grande en la coyuntura.
Dale a cada ingeniero un pequeño mono de bronce.
Cuando estás por ingresar al túnel, paras tu tren. Da vueltas en el cuenco para ver si hay un mono de bronce en el cuenco.
Si hay un mono, alguien más está utilizando el túnel, por lo que debes esperar hasta que el tren esté completamente en el túnel, momento en el que el conductor sale del furgón y saca al mono del cuenco.
Si no hay mono, nadie más está usando el túnel. Entonces, puedes agarrar a tu mono del compartimiento del motor, ponerlo en el recipiente y conducir a través del túnel, sabiendo que has adquirido acceso exclusivo a la pista. Por supuesto, te detienes brevemente a permitir que el conductor recupere el mono de bronce.
¿Adivina qué?
¡ Todavía tenían colisiones!
¿Por qué? ¿Cuál es la situación o secuencia de acciones que hace que esto falle?
Esa es una condición de carrera.
En un documento escrito, puede explicar cómo la condición de carrera conduce a un accidente.
En una presentación, puede entrenar a la audiencia a través del razonamiento sobre concurrencia y bloqueo.
Iba a recomendar a los filósofos del comedor, pero veo que ya has encontrado ese. Entonces, como alternativa, ¿qué tal usar el bloqueo como una analogía?
Imagine un tráfico normal a lo largo de las cuatro calles al lado de una sola cuadra de la ciudad (North Ave, South Ave, East Street y West Street). Cuando solo hay uno o dos autos en la carretera, todo se mueve sin problemas. Cuando hay tráfico constante, algunos autos tendrán que detenerse y esperar a que otros autos pasen, pero este es un problema manejable. Un automóvil se detiene para esperar que pase otro automóvil, y luego continúa su camino feliz.
Ahora, imagina tráfico de hora punta en el mismo lugar. Digamos que un automóvil que circula hacia el sur en West Street no puede atravesar la intersección en la esquina noroeste de nuestra manzana. Ese auto ahora bloquea todo el tráfico cruzado hacia el oeste en North ave. No pasa mucho tiempo antes de que un automóvil Westbound intente atravesar la intersección de esquina con NorthEast y se atasque, bloqueando todo el tráfico de Northbound en East street. Cuando esta situación hace que todo el camino alrededor de las cuatro intersecciones, ¡ningún automóvil puede moverse! Cada uno está esperando que los autos enfrente avancen, pero no hay forma de revertir el embotellamiento sin sacar los autos hacia atrás.
La comparación con la informática debe ser sencilla. Los automóviles son hilos o procesos, las calles y avenidas son procesadores, búferes o núcleos. El concepto de bloqueo se puede describir usando semáforos o señales de alto, y todo comienza a tener un sentido intuitivo, incluso para los no programadores.
La empresa X tiene $ 1,000 en el banco. X paga una renta de $ 2,000 y recibió un pago de $ 10,000 por servicios prestados a la empresa Y. Sin embargo, debido a una condición de carrera, X tiene un déficit de $ 1,000 y ahora está solicitando la bancarrota. = (
Es posible que desee explicar cómo el banco maneja la cuenta de la compañía X de esta manera: el personal A del banco toma el valor actual de $ 1,000 y le agrega $ 10,000. El personal del banco B toma el valor actual de $ 1,000 y le resta $ 2,000. El personal A del banco actualiza el valor a $ 11,000. El personal B del banco actualiza el valor a - $ 1,000.
Me decantaría por el enfoque de "comedor filósofo", pero dependiendo de mi público, trataría de analizarlo en el contexto de mi público. ¿Hablas con ejecutivos de negocios? Luego, analogícelo con algo así como asignar una sala de reuniones o un automóvil corporativo o reservar una habitación de hotel o lo que sea. ¿Estás hablando con gente promedio? Entonces, el ejemplo del filósofo del comedor está bien, o puede pensar en una situación similar que involucre el cuidado de animales de granja o sentarse en sillas o lo que sea.
Ya sea que secuestras el ejemplo del filósofo del comedor o que inventes el tuyo, definitivamente usa una metáfora.
Peter quiere salir de su entrada. Él comprueba que no haya nada en el camino de su auto, luego entra. Su hijo Frank se esconde detrás del auto. Peter no puede verlo y lo atropella.
Lo importante aquí es que para una computadora, "inspeccionar" y "modificar" tienden a ser dos acciones separadas, por lo que un buen ejemplo es que no puede verificar algo cuando lo modifica.
Si escribe a un público no técnico, querrá simplificar sus explicaciones y relacionarlo con algo que pueda entender. Una explicación tomada del artículo Analogies para enseñar cómputo paralelo a programadores inexpertos ( http://portal.acm.org/citation.cfm?doid=1189136.1189172 ) lo explica en términos de un juego de pen:
Vamos a jugar un juego llamado Pen Game. Las reglas son simples: voy a sostener un bolígrafo en mi mano, y luego diré "Uno, dos, tres, listo". Cuando digo "adelante", toma el bolígrafo de mi mano. Quien consigue la pluma gana. Listo? Uno, dos, tres, vamos.
Luego preguntas si el resultado de este juego puede predecirse por adelantado. Si no puede predecirse, ¿podemos garantizar un resultado correcto? Esto debería conducir a la comprensión de que es posible obtener resultados incorrectos para escrituras simultáneas en la misma pieza de memoria.
Usaría un ejemplo de cuenta bancaria de memoria compartida de una condición de carrera de datos.
explique que la computadora hace algo como: equilibrio de carga; agregar 1; equilibrio de la tienda ;. considere dos hilos que están modificando el saldo de su cuenta bancaria (usted y su esposa están depositando un dólar al mismo tiempo).
si ambos hilos se interrumpen después del: balance de carga; y luego reanudar, puedes perder un dólar.
Como mencionaste, a menudo necesitas introducir otros conceptos (exclusión mutua, hilos de ejecución) para describir con precisión las condiciones de carrera, incluso en una metáfora. Por lo tanto, intente definir estos términos (o al menos transmitir la idea) primero, utilizando la metáfora.
Como un ejemplo simple, usemos una intersección de 4 vías (establecida en un país donde conduce a la derecha). Divida la intersección en 4 cuadrantes: Noroeste, Noreste, Sudeste y Sudoeste. Ahora llame a cada cuadrante un recurso y llame a cada automóvil un hilo de ejecución. Estos autos solo respetan los sistemas de tráfico, y dado que no hay señales de alto o semáforos en esta intersección, los autos se desplazan sin disminuir la velocidad ni considerar el tráfico.
Puede demostrar fácilmente que el uso simultáneo de uno de estos cuadrantes en más de un automóvil es malo y provoca un accidente automovilístico. Una solución obvia es instalar un sistema de tráfico. El sistema garantiza que no más de un automóvil pase por un cuadrante al mismo tiempo. Puede hacer esto intrincadamente, sin bloquear todos los recursos. Por ejemplo, dejar que los automóviles provenientes del sur giren a la izquierda para dirigirse al oeste (usando los cuadrantes surorientales y noroccidentales), mientras que los que vienen del oeste giren a la derecha para dirigirse al sur (usando el cuadrante sudoeste) . El sistema de tráfico proporciona exclusión mutua o impide el uso simultáneo (por varios vehículos) de un recurso común (el cuadrante de la carretera en la intersección).
Esto al menos proporciona las ideas detrás de estas definiciones, la idea de que el acceso simultáneo a los recursos compartidos puede ser malo, y que la exclusión mutua puede resolver este problema. Una vez establecido esto, deberá asignarlos a una metáfora más apropiada para mostrar qué es una condición de carrera y cómo es una de esas cosas malas que resulta de la falta de exclusión mutua de un recurso común.
Lleva un poco más de tiempo, pero otorga cierta familiaridad con los términos y el panorama general antes de profundizar en una metáfora más compleja.
Envíelos a condición de carrera en Wikipedia.
La primera parte tendrá sentido, y el resto (que no se muestra a continuación) te hará ver inteligente, ya que supondrán que lo entiendes.
"Una condición de carrera o peligro de carrera es un defecto en un sistema o proceso por el cual la salida y / o el resultado del proceso dependen inesperada y críticamente de la secuencia o el tiempo de otros eventos. El término se origina con la idea de dos señales corriendo cada una otro para influir en la salida primero ".
Creo que el punto clave que hay que transmitir es que, con frecuencia, es un problema de tiempo que puede ser impredecible porque el tiempo que toma algo difiere de vez en cuando.
Una dificultad para explicar el concepto general es que las condiciones de carrera se manifiestan en una amplia variedad de situaciones. Si su objetivo es darle a su audiencia no técnica la sensación de que este es un tipo de problema genérico, debe intentar ofrecer más de un ejemplo.
Una imagen vale más que 1000 palabras. Es verdad. Si trazas una línea de tiempo y le pones cierta entidad, y muestras sus cambios de estado a medida que avanza el tiempo, puedes demostrar una condición de carrera con bastante facilidad en un diagrama. Puede tomar algunos redos para obtener la imagen correcta, pero siempre he descubierto que extraerla hace que mi punto sea más rápido que describirlo.
Hablar de dinero con sus partes interesadas podría llevarlos al pánico, especialmente si dan por sentado que están perdiendo dinero real debido a esto, que no es exactamente ideal si el problema no resulta específicamente en una pérdida neta de beneficios, así que aquí hay una orientación menos financiera historia sobre cómo puedes explicar una condición de carrera a cualquiera.
Esta historia no aborda el concepto de punto muerto , sino el escenario y las consecuencias de la condición racial más tradicional.
HISTORIA COMIENZA AQUÍ:
El escenario: hay 3 ciudades conectadas por una red ferroviaria. Los trenes no tienen ninguna señal que indique de qué ciudad provienen y a qué ciudad van porque están siendo utilizadas entre las 3 ciudades y la red ferroviaria no quería lidiar con la molestia de cambiar las señales. hora. Como la red es pequeña, no hay un cronograma concreto cuando los trenes llegan y se van. Los supervisores de la estación reciben una llamada de los otros supervisores de la estación cuando sale un tren, el supervisor toma nota del tiempo cuando se fue y, dado que todos los trenes son de los mismos modelos, conducen a la misma velocidad, por lo que cuando el capataz recibe una llamada de las otras ciudades anuncian a las personas en la estación que: "El próximo tren se dirigirá a la ciudad C". Entonces, las personas que deseen viajar a la ciudad C esperan el tren, se suben y se dirigen alegremente a la ciudad C.
El problema: Pero un día, mientras un tren estaba planeando su ruta de A a B, se rompió a mitad de camino entre A y B. Afortunadamente los técnicos son muy hábiles y podrían reparar el tren en poco tiempo. . Sin embargo, ese mismo día, otro tren también estaba planeando una ruta diferente de C a B a A. El capataz de la estación B recibió una llamada de A de que se acerca un tren, y poco después recibió otra llamada de C de que otro tren también venía. El supervisor de la estación anunció a los pasajeros que esperaban en la estación: "El primer tren que llegue se dirigirá a la estación C, y poco después el tren se dirigirá a la estación A". Cuando los pasajeros recogieron su equipaje y se dirigieron a sus respectivas plataformas. El capataz vio venir un tren y redirigió los rieles a la plataforma donde la gente planeaba dirigirse a la ciudad C. Poco sabían que el tren en realidad iba a ir a la ciudad A. El otro tren, después de haber solucionado sus problemas mecánicos, también llegó a la estación y el capataz lo dirigió alegremente a la plataforma que contenía pasajeros que deseaban ir a la ciudad A. No hace falta decir que ninguno de los pasajeros llegó donde lo planearon, todo porque el supervisor supuso que llegarían en orden como de costumbre.
El problema con las condiciones de carrera y muchas construcciones informáticas es que las personas no son computadoras. Cada vez que explico un algoritmo a mis alumnos, dicen "pero no tiene sentido hacerlo de esa manera", a lo que respondo que "las computadoras no tienen sentido común, todas tienen instrucciones". Aparte de eso, deberías explicar una condición de carrera como una carrera, y tiene más sentido dejar que la gente realmente pruebe la carrera, si es que pueden. De esa forma pueden ver cómo van las cosas mal. Pero ... no tienen permitido usar el sentido común.
Asumamos que tenemos un juego donde 2 personas llenan montones de bloques de colores en orden Rojo, Naranja, Amarillo. Tienen muchos bloques rojos, naranjas y amarillos. Todas las pilas deben tener exactamente tres bloques de alto.
En el primer juego ambos intentan hacer esto lo más rápido posible, pero solo funcionan en sus propios stacks.
En el segundo juego, intentan trabajar juntos permitiéndose también apilar bloques en las pilas de los demás. Sin embargo, no se les permite cambiar el bloque que tienen en la mano, y tienen que colocar un bloque planeado.
Puedes imaginar una situación como esta en la pila 1:
player 1 grabs a red block
player 1 places red block - player 2 grabs an orange block
player 1 grabs an orange block - player 2 places an orange block
player 1 places an orange block
Entonces ahora tenemos una pila con dos bloques anaranjados. Es obvio que con un juego humano esto nunca sucedería, porque las personas tienen sentido común: ven que el bloque naranja ya está colocado, y revierten su decisión de colocar también un bloque naranja.
También puedes mostrarles este video: https://www.youtube.com/watch?v=TcGwNdbsAbc
Usemos una pizarra para hacer una tarea de contabilidad trivial. Tenemos $ 100 a la mano, escríbalos en la pizarra.
Alice tiene docenas de facturas que suman $ 100, así que va a anotar esos $ 100, vaya y agregue su lista y regrese en 5 minutos y escriba $ 200 en la pizarra.
Bob ha estado de compras. Tomará ese número de la pizarra e irá y restará $ 50 en compras, y luego va a escribir $ 50 en la pizarra.
Si Bob vuelve primero, veremos $ 200 después de que Alice escriba su resultado. Si Alice regresa primero veremos $ 50, también está mal. Lo que queremos ver es $ 150, y debemos agregar algunas precauciones en algún lugar para que eso suceda.
Eso debería ser suficiente para anclar una discusión de soluciones técnicas con intuiciones razonables.
Por ejemplo, un mutex significa que bloquea la puerta de la sala con la pizarra y hace que hagan su trabajo allí. Una solución optimista significa que los verificará y volverá a comenzar si el número cambió mientras estaban ausentes. Si quieres hablar de puntos muertos, puedes reírte de que Bob llama a Alice desde la habitación cerrada para pedirle que se apure.
Escribir un programa:
- Espera por el salario.
- Ir a la tienda.
- Comprar comida.
- Enciende el plato.
- Pon comida en el plato.
- Mantenga la placa por 20 minutos.
- Comer.
- Acostarse.
Ahora intente tener dos hilos (usted, esposa) ejecutarlo sin sincronización.
- Tu: espera por el salario
Esposa: ve a la tienda sin dinero, accidente
Tú: enciende el plato.
- Usted: mantenga la placa por 20 minutos.
Tú: ve a la cama.
Esposa: comer en el lugar de otra persona.
- Esposa: vete a la cama