node.js中的低优先级作业

 zws3504075 发布于 2023-02-10 13:48

基于节点使用单个线程来管理所有内容的事实,我很好奇我应该如何处理低优先级的工作

这项工作是不断运行和分析数据(假设它是一个setTimeout),但它确实需要花费很多时间,我希望它在调度程序中具有非常低的优先级.

我不认为我可以在一个单独的进程中运行它,因为我需要经常修改它的工作指令(它使用我的主进程的变量,所以它需要能够不断访问它们).

您可以将其视为一大堆任务,它将不断工作,但这些任务的工作集由主进程控制.

一个单独的过程需要两者之间不断的请求来交换数据,所以这似乎是一个坏主意

一个单独的线程,比如Web工作者,可能会更快吗?我不知道节点是否支持它们

最好的事情是它是一个在计时器上运行的简单事件函数,它遵循节点的原则,但我需要以某种方式告诉调度程序在这个函数上花费的时间少于程序的其余部分.这有什么办法吗?

Benjamin Gru.. 8

首先让我先说:

一个大问题.

通常,出于显而易见的原因,在单线程环境中运行"后台任务"是有问题的.

让我们从最后开始,第三种方法.

使用带定时器的功能:

使用计时器运行第二个功能听起来不错,但它如何知道时间是否结束?

你可以这样做:

function myFunc(){
    var date = Date.now();
    while(date - Date.now() < 5 || nothingElseToDo()) { // 5 miliseconds
         // do something
    }
    setImmediate(myFunc); // continue processing after event loop did a cycle
}

然而,这不是真正有效或精确,5毫秒是很多.

你的第二种方法,一个线程怎么样?

或者,您可以使用threads_a_gogo 线程,这似乎非常适合您的用例创建后台线程.

注意:这不是一个可行的例子,threads_a_gogo在节点0.10.x中不起作用

他们在GitHub上有一个精心设计的例子(我在这里复制),展示了如何将线程与事件发射器一起使用:

quickIntro_evented_childThreadCode.js

//这是.load()编入子/后台线程的代码:

function fibo (n) {
    return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}

thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) {
    this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread.
});

主文件:

var thread= require('threads_a_gogo').create();
thread.load(__dirname + '/quickIntro_evented_childThreadCode.js');

//Emit 'giveMeTheFibo' in the child/background thread.
thread.emit('giveMeTheFibo', 35);

//Listener for the 'theFiboIs' events emitted by the child/background thread.
thread.on('theFiboIs', function cb (data) {
  process.stdout.write(data);
  this.emit('giveMeTheFibo', 35);
});

(function spinForever () {
  process.stdout.write(".");
  process.nextTick(spinForever);
})();

这种事件发射器,主要应用程序将事件发送到一个非常适合您的用例的线程.

我要做的是:

我也没有把我需要在后台处理的所有数据写入某个数据存储上的并发队列(可能是redis),然后异步地从NodeJS执行写入,然后我用我的'任务'代码读取它们(进程) ,是)执行这些任务.

这样,很明显这个任务实际上并不是正常服务器流的一部分.

1 个回答
  • 首先让我先说:

    一个大问题.

    通常,出于显而易见的原因,在单线程环境中运行"后台任务"是有问题的.

    让我们从最后开始,第三种方法.

    使用带定时器的功能:

    使用计时器运行第二个功能听起来不错,但它如何知道时间是否结束?

    你可以这样做:

    function myFunc(){
        var date = Date.now();
        while(date - Date.now() < 5 || nothingElseToDo()) { // 5 miliseconds
             // do something
        }
        setImmediate(myFunc); // continue processing after event loop did a cycle
    }
    

    然而,这不是真正有效或精确,5毫秒是很多.

    你的第二种方法,一个线程怎么样?

    或者,您可以使用threads_a_gogo 线程,这似乎非常适合您的用例创建后台线程.

    注意:这不是一个可行的例子,threads_a_gogo在节点0.10.x中不起作用

    他们在GitHub上有一个精心设计的例子(我在这里复制),展示了如何将线程与事件发射器一起使用:

    quickIntro_evented_childThreadCode.js

    //这是.load()编入子/后台线程的代码:

    function fibo (n) {
        return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
    }
    
    thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) {
        this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread.
    });
    

    主文件:

    var thread= require('threads_a_gogo').create();
    thread.load(__dirname + '/quickIntro_evented_childThreadCode.js');
    
    //Emit 'giveMeTheFibo' in the child/background thread.
    thread.emit('giveMeTheFibo', 35);
    
    //Listener for the 'theFiboIs' events emitted by the child/background thread.
    thread.on('theFiboIs', function cb (data) {
      process.stdout.write(data);
      this.emit('giveMeTheFibo', 35);
    });
    
    (function spinForever () {
      process.stdout.write(".");
      process.nextTick(spinForever);
    })();
    

    这种事件发射器,主要应用程序将事件发送到一个非常适合您的用例的线程.

    我要做的是:

    我也没有把我需要在后台处理的所有数据写入某个数据存储上的并发队列(可能是redis),然后异步地从NodeJS执行写入,然后我用我的'任务'代码读取它们(进程) ,是)执行这些任务.

    这样,很明显这个任务实际上并不是正常服务器流的一部分.

    2023-02-10 13:50 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有