Skip to content

Commit 800482d

Browse files
node-start
1 parent 3922b8f commit 800482d

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ typings/
7070
**/dist/**
7171
Note/oss-upload/.wj.config.js
7272
Deploy/minikube/registry/data
73+
Guides/node-start/node-v10.16.0/**

Guides/node-start.md

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
## Node.js 是如何执行的
2+
3+
### 下载源码并编译
4+
5+
```bash
6+
# 从官网下载 node 源码
7+
wget https://nodejs.org/dist/v10.16.0/node-v10.16.0.tar.gz
8+
# 解压
9+
tar -xzvf node-v10.16.0.tar.gz
10+
# 进入目录,配置并编译
11+
cd node-v10.16.0
12+
./configure --debug
13+
make -j 4
14+
15+
# 新建测试 js 文件
16+
# clion 导入目录, 修改配置, 使用 debug 下的 node执行测试 js 文件
17+
# 移除 before launch 中的 build task
18+
```
19+
20+
### 启动执行路径
21+
22+
* node_main.cc 定义 main 函数,程序执行由此开始
23+
* main 转调 node::Start(argc, argv), 此函数定义于 node.cc 文件
24+
* Start 函数,有以下几个重要步骤
25+
* `PlatformInit();`
26+
* `uv_setup_args(argc, argv);`
27+
* `Init(&args, &exec_args);`
28+
* `V8::Initialize();`
29+
* `Start(uv_default_loop(), args, exec_args);`
30+
31+
#### `PlatformInit();`
32+
* 确保文件描述符是有效的
33+
* 注册信号处理函数
34+
* `RegisterSignalHandler(SIGINT, SignalExit, true);`
35+
* `RegisterSignalHandler(SIGTERM, SignalExit, true);`
36+
37+
#### `uv_setup_args(argc, argv)`
38+
定义于 uv.h 中,用于对 process.title 的设置和读取
39+
40+
#### `Init(&args, &exec_args)`
41+
* 初始化 uptime 值(`prog_start_time = static_cast<double>(uv_now(uv_default_loop()));`
42+
* 配置 V8 环境变量
43+
* 标记 `node_is_initialized` 为 true
44+
45+
#### `V8::Initialize()`
46+
* 初始化 v8 引擎
47+
48+
#### `Start(uv_default_loop(), args, exec_args)`
49+
* 准备工作新建实例等等
50+
* 加载环境变量 `Start(isolate, isolate_data.get(), args, exec_args);` -> `LoadEnvironment(&env)`
51+
* 开启事件循环 `Start(isolate, isolate_data.get(), args, exec_args);` -> `uv_run(env.event_loop(), UV_RUN_DEFAULT);`
52+
* 收尾,内存回收
53+
54+
55+
### 事件循环
56+
```c++
57+
int uv_run(uv_loop_t* loop, uv_run_mode mode) {
58+
int timeout;
59+
int r;
60+
int ran_pending;
61+
62+
r = uv__loop_alive(loop);
63+
if (!r)
64+
uv__update_time(loop);
65+
66+
while (r != 0 && loop->stop_flag == 0) {
67+
uv__update_time(loop);
68+
uv__run_timers(loop);
69+
ran_pending = uv__run_pending(loop);
70+
uv__run_idle(loop);
71+
uv__run_prepare(loop);
72+
73+
timeout = 0;
74+
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
75+
timeout = uv_backend_timeout(loop);
76+
77+
uv__io_poll(loop, timeout);
78+
uv__run_check(loop);
79+
uv__run_closing_handles(loop);
80+
81+
if (mode == UV_RUN_ONCE) {
82+
/* UV_RUN_ONCE implies forward progress: at least one callback must have
83+
* been invoked when it returns. uv__io_poll() can return without doing
84+
* I/O (meaning: no callbacks) when its timeout expires - which means we
85+
* have pending timers that satisfy the forward progress constraint.
86+
*
87+
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
88+
* the check.
89+
*/
90+
uv__update_time(loop);
91+
uv__run_timers(loop);
92+
}
93+
94+
r = uv__loop_alive(loop);
95+
if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
96+
break;
97+
}
98+
99+
/* The if statement lets gcc compile it to a conditional store. Avoids
100+
* dirtying a cache line.
101+
*/
102+
if (loop->stop_flag != 0)
103+
loop->stop_flag = 0;
104+
105+
return r;
106+
}
107+
```
108+
109+
43.4 MB
Binary file not shown.

0 commit comments

Comments
 (0)