13 Stimmen

Welche Operationen in Node sind thread-safe?

Ich benutze dieser Ansatz um Daten in einem globalen Array zu speichern, das einen http-Server hostet, auf dem bestimmte Anfragen das globale Array manipulieren.

Ich bin irgendwie besorgt über das Laufen in Threading Probleme mit bestimmten Operationen - vor allem push et splice . Ich stelle mir vor, dass ich bei einer Anfrage über das Array iterieren und Elemente auf der Grundlage einer Bedingung entfernen muss, während ich bei einer anderen Anfrage .push() auf dem Array, dass ich auf Probleme stoßen werde. Kann jemand dies bestätigen?

Ich schreibe meist in C#, wo selbst ein einfaches Inkrement nicht thread-sicher ist (der Start von 25 Threads, die i++ ausführen, garantiert nicht, dass i == 25 ist).

Update :

Ich habe 5 Beispiele geschrieben, um zu zeigen, wovon ich spreche. Test 1 und Test 3 funktionieren gut. Test 2 schlägt fehl, weil... was man normalerweise als Threading-Probleme bezeichnen würde (ob es sich nun um tatsächliche CPU-Threads handelt oder nicht). Test 4 und 5, wenn sie parallel laufen, scheinen zu funktionieren (d.h. sie haben keine Kollisionsprobleme wie Test 2).

http://pastebin.com/HcJHTDFY

Ich verwende ApacheBench zum Testen und stelle 1000 parallele Anfragen.

Dies führt mich zu glauben, dass Test 1 und Test 3 gut funktionieren, weil nodejs nicht mehr als 1 ausführen wird Instanz des app.get('/test3'...) paralleler Rückruf javascript-Funktion parallel (blockierend?). Sobald Sie ein setInterval/setTimeout implementieren, gibt es nodejs frei, um eine andere Instanz des Rückrufs auszuführen (nicht blockierend?).

Ich versuche wirklich nur zu verstehen, was zum Teufel non-blocking I/O model wirklich bedeutet. Bedeutet es, dass "hey, es ist möglich, nicht-blockierende mit setTimeout und setInterval zu tun, wenn Sie nicht-blockierende benötigen, andernfalls werden wir blockieren alle anderen Funktionen der äußeren Ebene von ausgeführt werden, bis wir die Funktion, die wir auf erschöpfen"? Ich denke, es ist wichtig, dies zu wissen, damit ich mich nicht in Schwierigkeiten bringe, wenn ich denke, ich könnte etwas wie /test2 implementieren und wäre völlig sicher.

Auch wenn ich versuche, non-blocking mit meinen Rückrufen zu sein, sollte ich wirklich aufgerufen werden setTimeout(code, 1) ? Oder gibt es einen besseren Weg?

22voto

Raynos Punkte 162170

Alle sind fadensicher.

Es gibt keine Threads, JavaScript ist single threaded, es ist unmöglich, dass zwei Javascript-Anweisungen zur gleichen Zeit laufen.

Nebenbei bemerkt, sollten Sie sowieso keine Globals verwenden, denn Globals sind böse

Edita:

Test 2 schlägt fehl, weil Sie asynchrone Rückrufe verwenden, was bedeutet, dass die Kontrolle an den Knoten zurückgeht und dieser weitere Anforderungen verarbeiten kann. Dies schafft Race Conditions wie gesehen.

In Node wird alles, was nicht asynchron ist, blockiert. Die einzigen asynchronen Dinge, die Sie haben, sind setTimeout/setInterval/process.nextTick und alle asynchronen IO-Operationen.

Man sollte das Rechnen nicht manuell asychron machen. Man sollte nur vermeiden, zu viel zu rechnen.

Ich habe einen Artikel geschrieben über Was es bedeutet, nicht blockierend zu sein

-5voto

ming_codes Punkte 2800

Raynos hat größtenteils recht. Aber nur weil JavaScript single threaded ist, heißt das nicht, dass Sie Ihre Wachen herunterlassen können. Man muss sich immer noch der Threads bewusst sein. Ein gutes Beispiel dafür ist, wie socket.io die Verbindung mit verschiedenen Clients aufrechterhält und dennoch in der Lage ist, diese Clients zu verfolgen.

Die funktionale Programmierung von JavaScript funktioniert durch Variablenbindung (wie...VIEL). Wenn man sich der Threads nicht bewusst ist, geht man fälschlicherweise davon aus, dass die Variablen richtig gebunden sind. Wie beim socket.io-Beispiel: Wie können Sie sicher sein, dass die Verbindung, die Sie erhalten, der Client ist, von dem Sie glauben, dass Sie ihn erhalten? Was ist, wenn die Referenzbindung falsch ist und die Verbindung tatsächlich auf einen anderen Client verweist?

Das ist die Art von Dingen, auf die Sie achten müssen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X