最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

这个代码可以在socket io中引起竞争条件吗?

IT培训 admin 6浏览 0评论

这个代码可以在socket io中引起竞争条件吗?

我是节点js和socket 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;
};
回答如下:

不,这里没有竞争条件。 node.js中的Javascript是单线程和事件驱动的,因此一次只执行一个socket.io事件处理程序。这是来自单线程模型的良好编程简化之一。它运行给定的执行线程,然后才会从事件队列中获取下一个事件并运行它。

希望您确实意识到所有socket.io连接都访问相同的counter变量。虽然这不是竞争条件,但这意味着只有一个counter,所有socket.io连接都能够修改。

如果你想要一个每连接计数器(每个连接的separeate计数器),那么你可以在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.当时可以免费运行其他操作。如果另一个操作也可以运行此代码,那么它将对flag的值进行操控,并且我们会遇到并发问题。

因此,您必须知道,无论何时进行异步操作,然后其余逻辑继续在异步操作的回调中,其他代码都可以运行,并且此时可以访问任何共享变量。您需要制作共享数据的本地副本,或者需要为共享数据提供适当的保护。

在这种特殊情况下,标志可以递增和递减,而不是简单地设置为truefalse,它可能用于跟踪此文件是否是当前正在读取的所需目的。

这个代码可以在socket io中引起竞争条件吗?

我是节点js和socket 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;
};
回答如下:

不,这里没有竞争条件。 node.js中的Javascript是单线程和事件驱动的,因此一次只执行一个socket.io事件处理程序。这是来自单线程模型的良好编程简化之一。它运行给定的执行线程,然后才会从事件队列中获取下一个事件并运行它。

希望您确实意识到所有socket.io连接都访问相同的counter变量。虽然这不是竞争条件,但这意味着只有一个counter,所有socket.io连接都能够修改。

如果你想要一个每连接计数器(每个连接的separeate计数器),那么你可以在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.当时可以免费运行其他操作。如果另一个操作也可以运行此代码,那么它将对flag的值进行操控,并且我们会遇到并发问题。

因此,您必须知道,无论何时进行异步操作,然后其余逻辑继续在异步操作的回调中,其他代码都可以运行,并且此时可以访问任何共享变量。您需要制作共享数据的本地副本,或者需要为共享数据提供适当的保护。

在这种特殊情况下,标志可以递增和递减,而不是简单地设置为truefalse,它可能用于跟踪此文件是否是当前正在读取的所需目的。

发布评论

评论列表 (0)

  1. 暂无评论