2016-08-27 4 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

Нет, состояние гонки здесь нет. Javascript в node.js является однопоточным и управляемым событием, поэтому только один обработчик события socket.io выполняется одновременно. Это одно из приятных упрощений программирования, которые исходят от однопоточной модели. Он выполняет заданный поток выполнения до завершения, а затем и только тогда он захватывает следующее событие из очереди событий и запускает его.

Надеюсь, вы поймете, что к той же переменной counter обращаются все соединения socket.io. Хотя это не состояние гонки, это означает, что существует только один counter, что все соединения socket.io могут быть изменены.

Если вам нужен счетчик для каждого соединения (разделительный счетчик для каждого соединения), вы можете определить переменную counter внутри обработчика io.on('connection', ....).


Условие гонки вы должны следить за в Node.js, когда вы сделать вызов асинхронного, а затем продолжить остальную часть вашего кодирования логики в асинхронном обратном вызове. Пока выполняется асинхронная операция, другой код node.js может запускаться и может изменять общедоступные переменные, которые вы можете использовать. Это не относится к вашему примеру counter, но это происходит с большим количеством других типов программирования node.js.

Например, это может быть проблемой:

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; 
    }); 
} 

В этом случае, сразу же после того, как мы называем fs.readFile(), мы возвращаем управление обратно Node.js. В это время бесплатно выполнять другие операции. Если другая операция может также запустить этот код, тогда он будет tromp на значение flag, и у нас будет проблема параллелизма.

Итак, вы должны знать, что в любое время, когда вы выполняете операцию асинхронизации, а затем остальная часть вашей логики продолжается в обратном вызове для операции async, которую может выполнять другой код, и к нему могут быть доступны любые общие переменные. Вам либо нужно сделать локальную копию общих данных, либо вам необходимо обеспечить соответствующую защиту для общих данных.

В этом конкретном случае флаг может быть увеличен и уменьшен, а не просто установлен на true или false, и это, вероятно, послужит желаемой цели для отслеживания того, читается ли этот файл в настоящее время.

+0

Спасибо другу ... – cgon

+0

Добавлен еще несколько примеров. – jfriend00