Javascript/Node 中从不执行用户代码的隐藏线程:是否可能,如果可能,是否会导致竞争条件的神秘可能性? [英] Hidden threads in Javascript/Node that never execute user code: is it possible, and if so could it lead to an arcane possibility for a race condition?

查看:15
本文介绍了Javascript/Node 中从不执行用户代码的隐藏线程:是否可能,如果可能,是否会导致竞争条件的神秘可能性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据评论/回答,请参阅问题底部的更新:这个问题实际上是关于不执行回调的隐藏线程的可能性.

See bottom of question for an update, based on comments/answers: This question is really about the possibility of hidden threads that do not execute callbacks.

我有一个关于涉及节点请求模块的潜在神秘场景的问题,其中:

I have a question about a potential arcane scenario involving the Node Request module in which:

  • 一个完整的 HTTP 请求在网络上被构建和执行(需要多少毫秒甚至秒)

  • A complete HTTP request is constructed and executed over the network (taking however many ms or even seconds)

... 之前在本地机器上运行时执行单个函数(通常以纳秒为单位?) - 详情见下文

... before a single function is executed at runtime on the local machine (typically in the nanoseconds?) - see below for details

我发布这篇文章主要是为了健全性检查,只是为了确保我没有误解 Node/JS/Request 模块代码.

I am posting this mostly as a sanity check just to make sure I am not misunderstanding something about Node / JS / Request module code.

来自请求模块中的示例(请参阅该部分中的第二个示例),这是:

From the examples in the Request module (see the SECOND example in that section), is this:

// Copied-and-pasted from the second example in the 
// Node Request library documentation, here:
// https://www.npmjs.com/package/request#examples

// ... My ARCANE SCENARIO is injected in the middle

var request = require('request')
  request(
    { method: 'GET'
    , uri: 'http://www.google.com'
    , gzip: true
    }
  , function (error, response, body) {
      // body is the decompressed response body 
      console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity'))
      console.log('the decoded data is: ' + body)
    }
  )

    // **************************************************** //
    // Is the following scenario possible?
    //
    // <-- HANG HANG HANG HANG HANG HANG HANG HANG HANG -->
    //
    // Let us pretend that the current thread HANGS here,
    // but that the request had time to be sent,
    // and the response is pending being received by the thread
    //
    // <-- HANG HANG HANG HANG HANG HANG HANG HANG HANG -->
    // **************************************************** //

.on('data', function(data) {
    // decompressed data as it is received 
    console.log('decoded chunk: ' + data)
  })
  .on('response', function(response) {
    // unmodified http.IncomingMessage object 
    response.on('data', function(data) {
      // compressed data as it is received 
      console.log('received ' + data.length + ' bytes of compressed data')
    })
  })

我已经在代码片段中指出了我的神秘场景.

I have indicated my arcane scenario in the code snippet.

假设 Node 进程在指定的点挂起,但该 Node 在内部(在隐藏线程中,对 Javascript 不可见,因此不调用任何回调)是可以的构造请求,并通过网络发送;假设挂起一直持续到接收到一个响应(比如两个块)并等待 Node.js 处理.(这种场景当然很神秘,我不确定理论上是否可行.)

Suppose the Node process hangs at the point indicated, but that Node internally (in a hidden thread, invisible to Javascript, and therefore not calling any callbacks) WAS able to construct the request, and send it over the network; suppose the hang continues until a response (in two chunks, say) is received and waiting to be processed by Node. (This is the scenario that is certainly arcane, and that I'm not sure is even theoretically possible.)

然后假设挂起结束,上面的 Node 线程被唤醒.此外,假设(以某种方式)Node 能够一直处理响应,直到执行上述代码中的回调函数为止(但没有越过原始代码路径中代码中的挂起"点——再次,如果这在理论上是可能的).

Then suppose that the hang ends, and the Node thread above wakes up. Further, suppose that (somehow) Node was able to process the response all the way to the point of executing the callback function in the code above (yet without moving past the 'hanged' point in the code in the original code path -- again, if this is even theoretically possible).

上述神秘场景在理论上可行吗?如果是这样,在 'data' 事件被安排在对象上之前,数据包不会通过网络接收并组合,准备传递给回调函数吗?在这种情况下,如果可能的话,我想会错过 'data' 事件.

Is the above arcane scenario theoretically possible? If so, wouldn't the data packets be received over the network and combined, ready to be passed to the callback function, before the 'data' event was scheduled on the object? In this case, if it's possible, I would imagine that the 'data' event would be missed.

再一次,我明白这是一个神秘的场景 - 考虑到所涉及的内部机制和编码,这在理论上甚至是不可能的.

Again, I understand that this is an arcane scenario - perhaps it's not even theoretically possible, given the internal mechanisms and coding involved.

那是我的问题 - 上面的神秘场景及其极不可能的竞争条件在理论上是可能的吗?

That is my question - is the above arcane scenario, with its extremely unlikely race condition, nonetheless theoretically possible?

我只是为了确保我没有遗漏一些关键点.谢谢.

I ask just to make sure I'm not missing some key point. Thanks.

更新:来自评论和回答: 我现在已经澄清了我的问题.神秘场景"需要有一个 HIDDEN 线程(因此不能执行任何用户代码,包括 CALLBACKS)来构造请求,通过网络发送它并接收响应 - 没有任何回调要触发,包括'data' 回调 - 并在 'response' 回调准备好被调用时停止,等待(单个)可见 JS 线程唤醒.

UPDATE: From comments & answers: I now have clarified my question. The 'arcane scenario' would require that there is a HIDDEN thread (which therefore CANNOT execute any USER code, including CALLBACKS) that constructs the request, sends it over the network, and receives the response - WITHOUT having any callbacks to trigger, including the 'data' callback - and stops short just at the point that the 'response' callback is ready to be called, waiting for the (single) visible JS thread to wake up.

推荐答案

不,这不可能发生.

是的,确实有隐藏的"后台线程为异步方法工作,但那些不调用回调.javascript 的所有执行都同步、顺序地发生在同一个线程上.data 事件回调将始终异步执行,即在当前脚本/函数运行完成之后.

Yes, there are indeed "hidden" background threads that do the work for asychronous methods, but those don't call callbacks. All execution of javascript does happen on the same thread, synchronously, sequentially. That data event callback will always be executed asynchronously, that is, after the current script/function ran to completion.

虽然在回调创建并附加到事件发射器之前确实可能已经有来自网络的数据包到达,但在发送请求之前总是创建侦听最低级别数据包的回调 - 它是本机makeRequest"方法,并且可以从一开始就被调用.所以当一个数据包在当前脚本(仍然被构建事件发射器和附加处理程序占用)完成之前到达时,这个事件排队,并且回调只会在事件循环结束后执行准备好 - 在下一个回合.到那时,data 事件回调肯定创建并附加了.

While there could indeed already arrive packets from the network before the callback is created and attached to the event emitter, the callback that listens for packets on the lowest level is always created before the request is sent - it is an argument to the native "makeRequest" method, and is available to be called right from the beginning. So when a packet does arrive before the current script (still being occupied by constructing event emitters and attaching handlers) has finished, this event is queued up, and the callback will only be executed after the event loop is ready - on the next turn. By then, the data event callback is certainly created and attached.

这篇关于Javascript/Node 中从不执行用户代码的隐藏线程:是否可能,如果可能,是否会导致竞争条件的神秘可能性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆