Критический раздел в JavaScript (многопоточность)
Я думал, что мне никогда не понадобится обрабатывать проблемы синхронизации и критические разделы в JavaScript, потому что он однопоточный. Что ж...
проблема
Несколько веб-сайтов отправляют данные на несколько локально размещенных страниц, которые одновременно обращаются к одному и тому же фрагменту памяти, вызывая состояние гонки.
Вот простой код, который я только что написал, который позволит двум детям вычислять результат и отправлять его родителю:
window.addEventListener("load", function() {
//threads analogy in JavaScript!
if (location.search.length) {
//receiver
var query = decodeURIComponent(location.search.slice(1));
var data = JSON.parse(query).value;
//handle data.
//start CRITICAL SECTION
localStorage.storage = +localStorage.storage + data;
//end CRITICAL SECTION
location.href = "about:blank"; //exit
} else {
//master
sum = document.getElementById("sum");
sum.innerText = localStorage.storage = "0";
window.addEventListener("storage", function() {
//data received from receiver
sum.innerText = localStorage.storage;
});
}
});
Несколько страниц рассчитают число и отправят обратно родителю:
var frame = document.createElement("iframe");
frame.src = 'http://localhost:8080/master.html?{"value":1}'; //port 8080
document.body.appendChild(frame);
var n=0;
frame.addEventListener("load", function(){
if(n) document.body.removeChild(frame);
else n=1;
}
Поскольку localStorage используется совместно для страниц одного домена, и все эти страницы работают в разных потоках, это буквально вызывает состояние гонки в JavaScript.
Я попытался создать 2 экземпляра, каждый из которых одновременно и непрерывно возвращает значение 1
10 раз. Результат, который я получил в конце, всегда меньше 20.
В Си есть мьютекс, чтобы спасти наши жизни. Как мне подойти к этой проблеме в JavaScript, где нет механизмов блокировки?
Этот график может быть проще для понимания: