multitrådning - Behövs Mutexar i JavaScript?
Jag har sett den här länken: Implementing Mutual Exclusion in JavaScript. Å andra sidan har jag läst att det inte finns några trådar i JavaScript, men vad betyder det egentligen?
När händelser inträffar, var i koden kan de avbryta?
Och om det inte finns några trådar i JS, behöver jag använda mutexar i JS eller inte?
Specifikt undrar jag över effekterna av att använda funktioner som anropas av setTimeout() och XmlHttpRequest's onreadystatechange på globalt åtkomliga variabler.
Svar #1
Javascript definieras som ett reentrant-språk, vilket betyder att det inte finns någon trådhantering exponerad för användaren, det kan finnas trådar i implementationen. Funktioner som setTimeout() och asynkrona återuppringningar måste vänta på att skriptmotorn går i vila innan de kan köras.
Det betyder att allt som händer i ett händelseförlopp måste vara klart innan nästa händelse kan bearbetas.
Det sagt, kan du behöva en mutex om din kod gör något där den förväntar sig att ett värde inte förändras mellan när den asynkrona händelsen utlösts och när callbacken kallades.
Till exempel, om du har en datastruktur där du klickar på en knapp och den skickar en XmlHttpRequest som anropar en callback som ändrar datastrukturen på ett destruktivt sätt, och du har en annan knapp som ändrar samma datastruktur direkt, mellan det att händelsen utlösts och när callbacken exekverades skulle användaren kunna ha klickat och uppdaterat datastrukturen innan callbacken, vilket då kan leda till att värdet förloras.
Även om du skulle kunna skapa en race-condition som det är det väldigt enkelt att förhindra det i din kod eftersom varje funktion kommer att vara atomär. Det skulle faktiskt kräva mycket arbete och några ovanliga kodningsmönster för att skapa race-conditionen.
Svar #2
Svaren på denna fråga är dock lite föråldrade, även om de var korrekta när de gavs. Och de är fortfarande korrekta om man ser på en klient-sidig javascript-applikation som INTE använder webworkers.
Artiklar om webbarbetare:
multitrådning i JavaScript med webbarbetare
Mozilla om webbarbetare
Detta visar tydligt att javascript via web-workers har multitrådningskapacitet. När det gäller frågan om mutexar behövs i javascript? Jag är osäker på detta. Men detta stackoverflow-inlägg verkar relevant:
Ömsesidig uteslutning för N asynkrona trådar
Svar #3
Ja, mutexar kan vara nödvändiga i Javascript när man får åtkomst till resurser som delas mellan flikar/fönster, som localStorage.
Till exempel, om en användare har två flikar öppna, är enkel kod som följande osäker:
function appendToList(item) {
var list = localStorage["myKey"];
if (list) {
list += "," + item;
}
else {
list = item;
}
localStorage["myKey"] = list;
}
Mellan den tidpunkt då localStorage-elementet 'hämtas' (åtkomstmetoder) och 'anges' (mutatorer), kan en annan flik ha ändrat värdet. Det är generellt osannolikt, men möjligt - du måste själv bedöma sannolikheten och risken som är förknippad med eventuell konkurrens i dina specifika omständigheter.
Se följande artiklar för mer detaljer:
- Vänta, rör inte vid det: Ömsesidiga uteslutningslås & JavaScript - Medium Engineering
- JavaScript-samtidighet och låsning av HTML5 localStorage - Benjamin Dumke-von der Eh, Stackoverflow
