2016-08-27 14 views
3

私はノードjsとsocket ioを初めて使っています。このコードはカウンタ変数の競合状態につながりますか?カウンタ変数を安全に更新するためのロックライブラリを使用する必要があります。このコードはソケットioの競合状態を引き起こす可能性がありますか?

"use strict"; 

module.exports = function (opts) { 
    var module = {}; 

    var io = opts.io; 

    var counter = 0; 

    io.on('connection', function (socket) { 

     socket.on("inc", function (msg) { 
      counter += 1; 
     }); 

     socket.on("dec" , function (msg) { 
      counter -= 1; 
     }); 

    }); 


    return module; 
}; 

答えて

5

いいえ、ここに競合状態はありません。 node.jsのJavascriptはシングルスレッドでイベント駆動型なので、一度に1つのsocket.ioイベントハンドラしか実行されません。これは、単一のスレッドモデルから得られる素敵なプログラミング単純化の1つです。それは完了の実行の特定のスレッドを実行し、それだけでそれはイベントキューから次のイベントをつかみ、それを実行します。

同じcounter変数がすべてのsocket.io接続によってアクセスされていることをご存じでしょうか。これは競合条件ではありませんが、すべてのsocket.io接続が変更可能であることはcounterの1つだけであることを意味します。

接続ごとのカウンタ(各接続に独立したカウンタ)が必要な場合は、io.on('connection', ....)ハンドラ内にcounterという変数を定義できます。あなたは非同期呼び出しを行い、その後、非同期コールバックでのコーディングロジックの残りの部分を継続するときに、Node.jsの中に注意する必要があります


レースの条件があります。非同期操作が実行されている間、他のnode.jsコードが実行され、使用している可能性のある公開アクセス可能な変数を変更することができます。 counterの例ではそうではありませんが、他の多くのタイプのnode.jsプログラミングで発生します。我々はnode.js.コントロールを送り返すされ、fs.readFile()を呼び出した直後に、この場合、

var flag = false; 

function doSomething() { 
    // set flag indicating we are in a fs.readFile() operation 
    flag = true; 
    fs.readFile("somefile.txt", function(err, data) { 
     // do something with data 

     // clear flag 
     flag = false; 
    }); 
} 

例えば、これは問題である可能性がありその時点で他の操作を実行するのは無料です。別の操作でもこのコードを実行できる場合は、flagの値をトリムし、並行性の問題が発生します。

したがって、非同期操作を行い、残りのロジックが非同期操作のコールバックで引き続き実行され、他のコードが実行でき、その時点で共有変数にアクセスできることに注意する必要があります。共有データのローカルコピーを作成するか、共有データを適切に保護する必要があります。

フラグは、単にtrueまたはfalseに設定するのではなく、インクリメントおよびデクリメントすることができ、おそらくこのファイルが現在読み込まれているかどうかを追跡する目的に役立ちます。

+0

ありがとうございました... – cgon

+0

さらにいくつかの例を追加しました。 – jfriend00

関連する問題