随笔 - 34  文章 - 0 评论 - 270 阅读 - 15万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

前言

这里是重点:Nodejs 是由v8 engine,libuv和内置模块组成,可以将v8 engine和 libuv看成一个库,两者是以源码的方式直接编译执行node中去的。

这是一个广泛的介绍,后面会详细介绍Nodejs的生态圈。

V8 engine

V8官方文档 https://developers.google.com/v8/intro

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
        #include "include/v8.h"
    #include "include/libplatform/libplatform.h"
 
    using namespace v8;
 
    int main(int argc, char* argv[]) {
    // V8初试化.
    V8::InitializeICU();
    Platform* platform = platform::CreateDefaultPlatform();
    V8::InitializePlatform(platform);
    V8::Initialize();
 
    // 创建isolate.
    Isolate* isolate = Isolate::New();
    {
        Isolate::Scope isolate_scope(isolate);
 
        // 创建HandleScope.
        HandleScope handle_scope(isolate);
 
        // 创建context 环境.
        Local<Context> context = Context::New(isolate);
   
        // 引入环境.
        Context::Scope context_scope(context);
   
        // 创建字符串.
        Local<String> source = String::NewFromUtf8(isolate, "'Hello' + ', World!'");
   
        // 编译字符串.
        Local<Script> script = Script::Compile(source);
   
        // Run,并且获取返回值.
        Local<Value> result = script->Run();
   
        // 转换为utf8,并且打印出来.
        String::Utf8Value utf8(result);
        printf("%s\n", *utf8);
    }
 
    // 关掉v8.
    isolate->Dispose();
    V8::Dispose();
    V8::ShutdownPlatform();
    delete platform;
    return 0;
}

 

 上面代码展示了一个典型的V8使用例。

1.isolate 代表一个V8实例,各个isolate是独立的(隔绝的),isolate中的obj无法再另一个isolate中被使用。

2.context 代表执行js代码的虚拟机,在这个虚拟机中,集成了一些功能,例如math,json,date(),RegExp()等。一个isolate可以同时存在多个context,这些context可以自由切换。如下图所示。

3.在V8 engine中,通过handle访问存在与heap上的js obj,如local,persistent,eternal,在V8中,有一个handle stack用于管理这些handles,如下图所示。

libuv

libuv主要用于处理事件驱动的异步IO模型,官方文档 http://nikhilm.github.io/uvbook/ 

libuv通过epoll,kqueue,event ports和IOCP来实现异步network IO。file,dns的操作则依赖于thread pool 来实现,正如上图所示。

libuv的重点是IO和event loop,loop负责调度callback,运行idle function,执行轮询等操作。

Nodejs

除了V8 engine和libuv ,Nodejs本身也做了很多的工作,它提供了js模块,c++模块等核心模块供开发者使用。

Nodejs 将这些核心js模块命名为native module,c++模块命名为builtin module,內建的c++模块则安放于node源码lib目录下。

下图为native module和builtin module编译及加载到内存的全过程。

当 node test.js 执行时,node_main.cc首先被调用,这一步初始化了V8 engine和libuv执行环境。

uv_run(env->event_loop,UV_RUN_ONCE)用于启动libuv event loop,而我们的js代码则会被传递到creatEnvironment(),最后交由V8处理。

查看Node.cc代码,可以看到一些函数与V8交互的工作,例如context,handle等的创建。

在js中,类似基于prototype继承的方式来实现的,通过V8提供的c++ API来完成这些操作。

 

posted on   peiyu1988  阅读(1811)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示