Werden Mutexe in Javascript benötigt?

Lesezeit: 7 Minuten

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 keine Threads in JS gibt, muss ich dann Mutexe in JS verwenden oder nicht?

Insbesondere wundere ich mich über die Auswirkungen der Verwendung von Funktionen, die von aufgerufen werden setTimeout() und XmlHttpRequest‘s onreadystatechange auf global zugänglichen Variablen.

Javascript ist definiert als ein wiedereintretend Sprache, was bedeutet, dass dem Benutzer kein Threading angezeigt wird, es können Threads in der Implementierung vorhanden sein. 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, abgeschlossen sein muss, bevor das nächste Ereignis verarbeitet wird.

Davon abgesehen 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 Aufruf des Rückrufs nicht ändert.

Wenn Sie beispielsweise eine Datenstruktur haben, bei der Sie auf eine Schaltfläche klicken und diese eine XmlHttpRequest sendet, die einen Callback aufruft, ändert dies die Datenstruktur auf destruktive Weise, und Sie haben eine andere Schaltfläche, die dieselbe Datenstruktur direkt ändert, während das Ereignis stattfand ausgelöst und wenn der Rückruf ausgeführt wurde, könnte der Benutzer vor dem Rückruf auf die Datenstruktur geklickt und diese aktualisiert haben, was dann den Wert verlieren 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 einige seltsame Codierungsmuster erforderlich, um die Race Condition tatsächlich zu erstellen.

  • Es ist überhaupt nicht schwer, diese Race-Bedingung zu erstellen: Zum Beispiel habe ich ein “onkeyup”-Ereignis in einem Feld, das einen Ajax-Aufruf an eine DB auslöst, um einige Werte zu erhalten. Das schnelle Eintippen von Daten kann leicht zu ungeordneten Ergebnissen führen.

    – thomasb

    17. November 2017 um 16:15 Uhr

Benutzer-Avatar
Gorillatron

Die Antworten auf diese Frage sind etwas veraltet, obwohl sie zu der Zeit, als sie gegeben wurden, richtig 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 auf Webworkern

Dies zeigt deutlich, dass Javascript über Web-Worker Multithreading-Fähigkeiten hat. In Bezug auf die Frage werden Mutexe in Javascript benötigt? Ich bin mir dessen nicht sicher. Aber dieser Stackoverflow-Beitrag scheint relevant zu sein:
Gegenseitiger Ausschluss für N asynchrone Threads

  • Explosion aus der Vergangenheit, aber ich bin auf die Notwendigkeit von Mutexes gestoßen, wenn mehrere Registerkarten auf denselben lokalen Speicher zugreifen

    – psp

    15. Mai 2014 um 13:46 Uhr

  • WebWorker wirken sich nicht auf den Wiedereintritt aus, da sie keinen Variablenstatus teilen und nur mit dem Haupt-Thread kommunizieren, indem sie Nachrichten weitergeben, die Ereignisse auslösen.

    – Alnitak

    1. August 2014 um 11:05 Uhr

Wie @william betont,

Möglicherweise benötigen Sie einen Mutex, wenn Ihr Code etwas tut, bei dem erwartet wird, dass sich ein Wert zwischen dem Auslösen des asynchronen Ereignisses und dem Aufruf des Rückrufs nicht ändert.

Dies kann weiter verallgemeinert werden – wenn Ihr Code etwas tut, bei dem er die exklusive 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 Backend zu erstellen. Möglicherweise benötigen Sie ein wenig Code, um Sie davor zu schützen, dass glückliche 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:

var save_lock = false;
$('#save_button').click(function(){
    if(!save_lock){
        //lock
        save_lock=true;
        $.ajax({
            success:function()
                //unlock
                save_lock = false;  
            }
        });
    }
}

Ich bin mir nicht sicher, ob das der beste Ansatz ist, und es würde mich interessieren, wie andere mit dem gegenseitigen Ausschluss in Javascript umgehen, aber soweit ich weiß, ist das ein einfacher Mutex und praktisch.

  • Ich würde dies kaum als Mutex bezeichnen, zumindest nicht im herkömmlichen Sinne, da zu keinem Zeitpunkt zwei Threads im Kontext eines einzelnen Blocks ausgeführt werden.

    – Oves

    20. Juli 2011 um 10:59 Uhr

  • Ein Mutex ist einfach ein Algorithmus, der hilft, „die gleichzeitige Verwendung einer gemeinsamen Ressource zu vermeiden“. Obwohl Multithreading Mutexe benötigt, gibt es nichts in der Definition, das besagt, dass ein Mutex spezifisch für die von Ihnen beschriebene Situation ist.

    – alzclarke

    21. Juli 2011 um 7:20 Uhr


  • Sie haben Recht mit der formalen Definition von Mutex. Aber das ist kaum das, woran die Leute denken, wenn sie über Mutexe in der realen Welt sprechen.

    – Oves

    21. Juli 2011 um 7:38 Uhr

  • Dies funktioniert nicht wie erwartet. Leider lösen wiederholte Klicks immer noch den Ajax-Aufruf aus. Irgendeine andere Idee?

    – Mohammed Shareef C

    21. Juli 2017 um 12:02 Uhr

  • Ziemlich sicher, dass dies in ein gewickelt werden sollte while mit setTimeout oder ein setInterval mit clearInterval nach n Fehlern, damit Sie eine Wiederholungs- und Zeitüberschreitungslogik haben. Wenn Sie es unverändert lassen, umgehen Sie nur den gesperrten Code. Der externe Umgang mit Mutexe und Shared Objects ist ebenso wichtig wie die Implementierungen selbst.

    – HerrMesees

    28. April 2019 um 20:06 Uhr

Ja, Mutexe können in Javascript erforderlich sein, wenn auf Ressourcen zugegriffen wird, die von Registerkarten/Fenstern gemeinsam genutzt werden, z lokaler Speicher.

Wenn ein Benutzer beispielsweise zwei Registerkarten geöffnet hat, ist einfacher Code wie der folgende unsicher:

function appendToList(item) {
    var list = localStorage["myKey"];
    if (list) {
        list += "," + item;
    }
    else {
        list = item;
    }
    localStorage["myKey"] = list;
}

Zwischen dem Zeitpunkt, zu dem das localStorage-Element „erhalten“ und „gesetzt“ wurde, 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, die mit einer Auseinandersetzung unter Ihren besonderen Umständen verbunden sind, selbst einschätzen.

Weitere Einzelheiten finden Sie in den folgenden Artikeln:

JavaScript ist Single-Threaded … obwohl Chrome ein neues Biest sein kann (ich denke, es ist auch Single-Threaded, aber jeder Tab hat seinen eigenen JavaScript-Thread … Ich habe mich nicht im Detail damit befasst, also zitieren Sie mich nicht dort).

Eine Sache, über die Sie sich jedoch Gedanken machen müssen, ist, wie Ihr JavaScript mit mehreren Ajax-Anforderungen umgeht, die nicht in der gleichen Reihenfolge zurückkommen, in der Sie sie gesendet haben. Alles, worüber Sie sich wirklich Sorgen machen müssen, ist sicherzustellen, dass Ihre Ajax-Aufrufe so behandelt werden, dass sie sich nicht gegenseitig auf die Füße treten, wenn die Ergebnisse in einer anderen Reihenfolge zurückkommen, als Sie sie gesendet haben.

Das gilt auch für Timeouts…

Wenn JavaScript Multithreading entwickelt, müssen Sie sich vielleicht Gedanken über Mutexe und dergleichen machen….

Benutzer-Avatar
Simon Buchan

JavaScript, das Sprache, kann so multithreaded sein, wie Sie möchten, aber Browsereinbettungen der Javascript-Engine führen jeweils nur einen Callback (onload, onfocus,

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy