Esto es posible en el caso de que las variables a
sean accedidas, digamos 2 trabajadores web a través de SharedArrayBuffer, así como algún script principal. La posibilidad es baja, pero es posible que cuando el código se compila en código máquina, los trabajadores web actualizan la variable a
justo a tiempo para que se cumplan las condiciones a==1
, a==2
y a==3
se satisfacen.
Este puede ser un ejemplo de condición de carrera en un entorno de subprocesos múltiples proporcionado por los trabajadores web y SharedArrayBuffer en JavaScript.
Aquí está la implementación básica de lo anterior:
main.js
// Main Thread
const worker = new Worker('worker.js')
const modifiers = [new Worker('modifier.js'), new Worker('modifier.js')] // Let's use 2 workers
const sab = new SharedArrayBuffer(1)
modifiers.forEach(m => m.postMessage(sab))
worker.postMessage(sab)
trabajador.js
let array
Object.defineProperty(self, 'a', {
get() {
return array[0]
}
});
addEventListener('message', ({data}) => {
array = new Uint8Array(data)
let count = 0
do {
var res = a == 1 && a == 2 && a == 3
++count
} while(res == false) // just for clarity. !res is fine
console.log(`It happened after ${count} iterations`)
console.log('You should\'ve never seen this')
})
modifier.js
addEventListener('message' , ({data}) => {
setInterval( () => {
new Uint8Array(data)[0] = Math.floor(Math.random()*3) + 1
})
})
En mi MacBook Air, sucede después de alrededor de 10 mil millones de iteraciones en el primer intento:
Segundo intento:
Como dije, las posibilidades serán bajas, pero dado el tiempo suficiente, llegará a la condición.
Sugerencia: si tarda demasiado en su sistema. Intenta solo a == 1 && a == 2
y cambia Math.random()*3
a Math.random()*2
. Agregar más y más a la lista reduce la posibilidad de golpear.