Skip to content

Instantly share code, notes, and snippets.

@ubershmekel
Created July 22, 2019 07:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ubershmekel/fc88307f827b3f0384c64117001c947b to your computer and use it in GitHub Desktop.
Save ubershmekel/fc88307f827b3f0384c64117001c947b to your computer and use it in GitHub Desktop.
An example race condition in JavaScript
// An example race condition in JavaScript
// When you run this script using Node or in a browser, you'll find it
// does not print "Ended with 0", but a random number. Even though the functions running
// simply loop 100 iterations of adding and subtracting. The reason the end result is random
// is because the sleeps are of random duration and the time between the read of the variable
// causes the eventual write to be incorrect when `adder` and `subber` interleave.
// This problem is similar to https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
let number = 0;
const times = 100;
function sleep() {
return new Promise((resolve) => setTimeout(resolve, Math.random() * 5));
}
async function adder() {
for (let i = 0; i < times; i++) {
await sleep();
let read = number;
read = read + 1;
await sleep();
number = read;
}
}
async function subber() {
for (let i = 0; i < times; i++) {
await sleep();
let read = number;
read = read - 1;
await sleep();
number = read;
}
}
async function main() {
console.log("Started with", number);
await Promise.all([
adder(),
subber(),
]);
console.log("Ended with", number);
}
main()
.then(() => console.log("All done"))
.catch((err) => console.error(err));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment