12

私はこのアプローチを使用して、特定のリクエストがグローバル配列を操作するhttpサーバーをホストするグローバル配列にデータを格納しています。

push特定の操作(主にと)でスレッドの問題が発生するのではないかと心配していspliceます。あるリクエストで配列を反復処理し、条件に基づいてアイテムを削除し、別のリクエストで.push()問題が発生する配列を呼び出す場合を想像します。誰かがこれを確認できますか?

私は主にC#で記述しますが、単純な増分でもスレッドセーフではありません(i ++を実行する25のスレッドを起動しても、結局のところi == 25であるとは保証されません)。

更新

私が話していることを示すために、5つの例を書きました。テスト1とテスト3は正常に機能します。テスト2は失敗します。これは、通常はスレッドの問題と呼ばれるもの(実際のCPUスレッドであるかどうかに関係なく)が原因です。テスト4と5は、並行して実行すると機能するように見えます(つまり、テスト2のような衝突の問題はありません)。

http://pastebin.com/HcJHTDFY

私はApacheBenchを使用してテストし、1000の並列リクエストを行っています。

これにより、nodejsは並列javascript関数でコールバックの複数のインスタンスをapp.get('/test3'...)並列に実行しないため(ブロッキング?)、テスト1とテスト3は正常に機能すると思います。setInterval / setTimeoutを実装するとすぐに、nodejsが解放され、コールバックの別のインスタンスが実行されます(ノンブロッキング?)。

私は本当に一体何をnon-blocking I/O model意味するのかを理解しようとしています。「ノンブロッキングが必要な場合は、setTimeoutとsetIntervalを使用してノンブロッキングを実行できます。そうしないと、実行中の関数がなくなるまで、他の外部レベルの関数の実行がブロックされます」という意味ですか。 ?/ test2のようなものを実装して完全に安全だと思って困らないように、これを知ることが不可欠だと感じています。

また、コールバックでブロックしないようにしようとしている場合、本当に呼び出す必要がありsetTimeout(code, 1)ますか?それとももっと良い方法はありますか?

4

2 に答える 2

18

すべてスレッドセーフです。

スレッドはありません。JavaScriptはシングルスレッドです。2つのjavascriptステートメントを同時に実行することはできません。

余談ですが、グローバルは悪なので、とにかくグローバルを使用するべきではありません

編集:

非同期コールバックを使用しているため、テスト2は失敗します。つまり、制御はノードに戻り、より多くの要求を処理できます。これにより、見られるような競合状態が発生します。

ノードでは、非同期ブロックではないものすべて。非同期のものは、setTimeout / setInterval/process.nextTickと非同期IO操作だけです。

手動で計算を非同期にするべきではありません。あまり多くの計算を行わないようにする必要があります。

ノンブロッキングとはどういう意味かについての記事を書きました

于 2012-04-04T23:39:47.867 に答える
-5

Raynosはほとんど正しいです。しかし、JavaScriptがシングルスレッドであるからといって、警戒を怠ることができるとは限りません。あなたはまだスレッドに注意する必要があります。これを説明する良い例は、socket.ioがさまざまなクライアントとの接続を維持し、これらのクライアントを追跡できる方法です。

JavaScriptの関数型プログラミング部分は、変数バインディング(... A LOTなど)によって機能します。スレッドを認識していないと、変数が正しくバインドされていると誤って想定することになります。socket.ioの例のように、取得している接続が、取得していると思われるクライアントであることをどのように確認できますか?参照バインディングが失敗し、接続が実際に別のクライアントを参照している場合はどうなりますか?

これはあなたが注意する必要があるタイプのことです。

于 2012-04-05T00:29:23.603 に答える