2

我在 libUV 的帮助下创建了一个 C node.js 插件以使插件异步。

我为此做了几个队列。

代码是这样的,loopArray用于存储那些队列:

//... variables declarations

void AsyncWork(uv_work_t* req) {
    // ...
}

void AsyncAfter(uv_work_t* req) {
    // ...
}

Handle<Value> RunCallback(const Arguments& args) {
    // ... some preparation work

    int loopNumber = (rand() % 10);
    int status = uv_queue_work(loopArray[loopNumber], &baton->request, AsyncWork, AsyncAfter);
    uv_run(loopArray[loopNumber]);
    return Undefined();

}


extern "C" {
    static void Init(Handle<Object> target) {
        int i = 0;
        for (i = 0; i< 10; i++){
            loopArray[i] = uv_loop_new();
        }           

        target->Set(String::NewSymbol("callback"), FunctionTemplate::New(RunCallback)->GetFunction());
    }
}

NODE_MODULE(addon, Init)

问题是,即使我为 CPU 要求高的任务创建了 10 个队列。node.js 在处理其中一个队列时不会在任务之间切换。是不是因为 node.js 的单线程特性?

是这样, uv_thread_create 是否有助于这种情况?

我找不到任何代码示例,所以我不知道如何使用它。

谢谢!

4

1 回答 1

4

这是节点架构背后的主要思想:使用函数调用(返回)和主事件循环来运行它们,而不是使用线程来并行处理多个作业。

如果您要做的是处理一系列作业,那么最好的方法是一次做一项作业。在系统上使用多个 cpu 内核是由多个节点实例而不是线程完成的。为此,我们有 child_process 和 cluster 节点模块。

当您创建多个线程时,假设您想为您的工作运行 10 个线程,如果您的系统有 8 个 cpu 内核,那么您通过给操作系统的调度程序提供不必要的工作来降低性能。这是您应该考虑的非常重要的一点。如果您有 8 个内核,那么如果您想要获得最大性能,则不应创建超过 8 个并行线程。

对于节点,我们不会尝试在一个进程中创建多个队列或线程。相反,我们采用多个节点进程,同样每个核心最多一个进程。

如果您要处理已经存在的队列。在这种工作中,您不需要 C 模块是异步的。

当我们有来自外部的作业(例如 Web 服务器上的 http 请求)时,我们需要异步行为。在 Web 服务器上,我们的工作以一种我们无法控制的方式出现。人们和其他机器可以随时连接到我们的服务器,我们希望尽快回复每个人。为此,我们不希望任何请求阻止其他人。我们需要并行处理尽可能多的请求。

但是,如果您在数据库表的行上运行或对一长串参数进行一些计算,那么您的业务就完全不同了。您的工作队列在您面前等待您的管理方式。您的工作不会以您无法控制的方式进入您的系统。在这种业务中,要达到极致的效率和最高的利润,你应该一个接一个地运行工作,不要在它们之间进行任何切换。并行性仅在您拥有多个内核并使用它们时才有用,节点的最佳实践是使用多个节点进程。

于 2012-06-27T16:28:03.830 回答