Ich habe diesen Link gesehen: Implementieren des gegenseitigen Ausschlusses in JavaScript . Andererseits habe ich gelesen, dass es in Javascript keine Threads gibt, aber was genau bedeutet das?
Wenn Ereignisse auftreten, wo im Code können sie unterbrechen?
Und wenn es in JS keine Threads gibt, muss ich in JS Mutexe verwenden oder nicht?
Insbesondere wundere ich mich über die Auswirkungen der Verwendung von Funktionen, die von setTimeout()
und aufgerufen werden XmlHttpRequest
, onreadystatechange
auf global zugängliche Variablen.
javascript
multithreading
mutex
Ovesh
quelle
quelle
Antworten:
Javascript ist als wiedereintrittsfähige Sprache definiert. Dies bedeutet, dass dem Benutzer kein Threading zur Verfügung steht und möglicherweise Threads in der Implementierung vorhanden sind. Funktionen wie
setTimeout()
und asynchrone Rückrufe müssen warten, bis die Skript-Engine in den Ruhezustand versetzt wurde, bevor sie ausgeführt werden können.Das bedeutet, dass alles, was in einem Ereignis passiert, beendet sein muss, bevor das nächste Ereignis verarbeitet wird.
Abgesehen davon benötigen Sie möglicherweise einen Mutex, wenn Ihr Code etwas tut, bei dem erwartet wird, dass sich ein Wert zwischen dem Auslösen des asynchronen Ereignisses und dem Aufrufen des Rückrufs nicht ändert.
Wenn Sie beispielsweise eine Datenstruktur haben, in der Sie auf eine Schaltfläche klicken und eine XmlHttpRequest sendet, die einen Rückruf aufruft, ändert sich die Datenstruktur destruktiv, und Sie haben eine andere Schaltfläche, die dieselbe Datenstruktur zwischen dem Zeitpunkt des Ereignisses direkt ändert ausgelöst und wenn der Rückruf ausgeführt wurde, hätte der Benutzer vor dem Rückruf auf die Datenstruktur klicken und diese aktualisieren können, wodurch der Wert verloren gehen könnte.
Während Sie eine solche Race-Bedingung erstellen könnten, ist es sehr einfach, dies in Ihrem Code zu verhindern, da jede Funktion atomar ist. Es wäre eine Menge Arbeit und würde einige seltsame Codierungsmuster erfordern, um die Rennbedingung tatsächlich zu erstellen.
quelle
Die Antworten auf diese Frage sind etwas veraltet, obwohl sie zum Zeitpunkt der Beantwortung korrekt waren. Und immer noch richtig, wenn Sie sich eine clientseitige Javascript-Anwendung ansehen, die KEINE Webworker verwendet.
Artikel über Web-Worker:
Multithreading in Javascript mit Webworkern
Mozilla über Webworker
Dies zeigt deutlich, dass Javascript über Web-Worker über Multithreading-Funktionen verfügt. In Bezug auf die Frage werden Mutexe in Javascript benötigt? Da bin ich mir nicht sicher. Dieser Stackoverflow-Beitrag scheint jedoch relevant zu sein:
Gegenseitiger Ausschluss für N asynchrone Threads
quelle
Wie @william betont,
Dies kann weiter verallgemeinert werden. Wenn Ihr Code etwas tut, bei dem er die ausschließliche Kontrolle über eine Ressource erwartet, bis eine asynchrone Anforderung aufgelöst wird, benötigen Sie möglicherweise einen Mutex.
Ein einfaches Beispiel ist eine Schaltfläche, die einen Ajax-Aufruf auslöst, um einen Datensatz im Back-End zu erstellen. Möglicherweise benötigen Sie ein wenig Code, um sich davor zu schützen, dass zufriedene Benutzer wegklicken und dadurch mehrere Datensätze erstellen. Es gibt eine Reihe von Ansätzen für dieses Problem (z. B. Deaktivieren der Schaltfläche, Aktivieren bei Ajax-Erfolg). Sie können auch ein einfaches Schloss verwenden:
Ich bin mir nicht sicher, ob dies der beste Ansatz ist, und ich würde gerne sehen, wie andere mit gegenseitigem Ausschluss in Javascript umgehen, aber soweit ich weiß, ist dies ein einfacher Mutex und praktisch.
quelle
while
mitsetTimeout
oder einsetInterval
mitclearInterval
nach n Fehlern eingeschlossen werden sollte, damit Sie Wiederholungs- und Zeitüberschreitungslogik haben. Wenn Sie den Status unverändert lassen, umgehen Sie nur den gesperrten Code. Der externe Umgang mit Mutexen und gemeinsam genutzten Objekten ist ebenso wichtig wie die Implementierungen selbst.JavaScript ist Single-Threaded ... obwohl Chrome ein neues Biest sein mag (ich denke, es ist auch Single-Threaded, aber jeder Tab hat seinen eigenen JavaScript-Thread ... Ich habe es nicht im Detail untersucht, also zitiere mich nicht Dort).
Eine Sache, über die Sie sich jedoch Sorgen machen müssen, ist, wie Ihr JavaScript mehrere Ajax-Anfragen verarbeitet, die nicht in derselben Reihenfolge zurückkommen, in der Sie sie senden. Alles, worüber Sie sich wirklich Sorgen machen müssen, ist sicherzustellen, dass Ihre Ajax-Anrufe so behandelt werden, dass sie sich nicht gegenseitig auf die Füße treten, wenn die Ergebnisse in einer anderen Reihenfolge als der von Ihnen gesendeten zurückgegeben werden.
Dies gilt auch für Auszeiten ...
Wenn JavaScript Multithreading erweitert, sollten Sie sich möglicherweise Gedanken über Mutexe und dergleichen machen.
quelle
Ja, in Javascript können Mutexe erforderlich sein, wenn auf Ressourcen zugegriffen wird , die von Registerkarten / Fenstern gemeinsam genutzt werden, z . B. localStorage .
Wenn ein Benutzer beispielsweise zwei Registerkarten geöffnet hat, ist einfacher Code wie der folgende unsicher:
Zwischen dem Zeitpunkt, an dem das localStorage-Element "got" und "set" ist, könnte eine andere Registerkarte den Wert geändert haben. Es ist im Allgemeinen unwahrscheinlich, aber möglich - Sie müssen die Wahrscheinlichkeit und das Risiko eines Konflikts unter Ihren besonderen Umständen selbst beurteilen.
Weitere Informationen finden Sie in den folgenden Artikeln:
quelle
JavaScript, die Sprache , kann beliebig multithreaded sein, aber Browser-Einbettungen der Javascript-Engine führen jeweils nur einen Rückruf (Onload, Onfocus, <Script> usw.) aus (vermutlich pro Registerkarte). Williams Vorschlag, einen Mutex für Änderungen zwischen dem Registrieren und dem Empfangen eines Rückrufs zu verwenden, sollte aus diesem Grund nicht zu wörtlich genommen werden, da Sie den dazwischenliegenden Rückruf nicht blockieren möchten, da der Rückruf, der ihn entsperrt, hinter dem aktuellen Rückruf blockiert wird ! (Wow, Englisch ist scheiße, wenn man über Threading spricht.) In diesem Fall möchten Sie wahrscheinlich etwas tun, um das aktuelle Ereignis erneut zu verteilen, wenn ein Flag gesetzt ist, entweder buchstäblich oder mit setTimeout ().
Wenn Sie eine andere Einbettung von JS verwenden und mehrere Threads gleichzeitig ausführen, kann dies etwas schwieriger werden. Aufgrund der Art und Weise, wie JS Rückrufe so einfach verwenden kann und Objekte beim Zugriff auf Eigenschaften sperrt, ist eine explizite Sperrung bei weitem nicht erforderlich . Es würde mich jedoch wundern, wenn eine Einbettung für allgemeinen Code (z. B. Game Scripting), die Multithreading verwendet, nicht auch einige explizite Sperrprimitive enthält.
Entschuldigung für die Textwand!
quelle
Ereignisse werden signalisiert, aber die JavaScript-Ausführung ist immer noch Single-Threaded.
Nach meinem Verständnis stoppt die Engine, wenn ein Ereignis signalisiert wird, was sie gerade ausführt, um den Ereignishandler auszuführen. Nach Abschluss des Handlers wird die Skriptausführung fortgesetzt. Wenn der Ereignishandler einige gemeinsam genutzte Variablen geändert hat, werden diese Änderungen im wieder aufgenommenen Code "aus heiterem Himmel" angezeigt.
Wenn Sie gemeinsam genutzte Daten "schützen" möchten, sollte ein einfaches boolesches Flag ausreichen.
quelle