nodejs初始化的文章相当的多,多看几篇文章基本就可以大体了解了。如果要从代码角度入手,我这里推一篇文章写的比较细
https://yq.aliyun.com/articles/682681?spm=a2c4e.11155472.0.0.2fcf777bSSoRJ2
这篇文章基本把nodejs的初始化从代码流程的角度比较详细的讲了一篇。我在这里进行一些补充
1.process这个对象是非常重要的,它承接JS与C++之间的接口调用
JS通过process.call(fun_name) -> c++ find from(PropertyList) by name -> c++ fuc.call
1)process到底是什么:上面的博客写到了函数SetupProcessObject为初始化process对象,为其添加各种属性。这个函数走完之后process 对象就能承接上下文正常工作了。那么这里就有凝问了process是什么对象,又是怎么增加属性的。还是从代码入手
nodejs初始化
process对象就是类Environment的process_object的函数返回值,process_object函数的申明和定义都是通过宏来实现的。在源码里面直接搜索是找不到的。nodejs里面存在大量的这种操作
文件src/env.h Environment对象申明里有这样一段代码
nodejs初始化ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES这个宏的定义如下nodejs初始化在这里我们看到了process_object,把 V(process_object, v8::Object) 这段话转换一下就如下
inline v8::Localv8::Object process_object() const;
inline void set_ process_object(v8::Localv8::Object value);
这里就申明了两个类方法,process就是process_object()的返回值,这下就明白了。那么process_object()实现呢,看下面

在类Environment最后面有这样一段代码
#define V(PropertyName, TypeName) Persistent PropertyName ## ;
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
#undef V
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES这个宏就是上面那个宏,如上图所示。转换这段代码可得
… //其它属性申明
Persistentv8::Object process_object
; //这里就申明了一个Persistent模版类的process_object_ 属性
…//其它属性申明

在env-inl.h里面最一段文字里面有如下语句nodejs初始化又是ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES这个宏。那么把对应的process_object转换下就成了下面所示
inline v8::Localv8::Object Environment::process_object() const {
return StrongPersistentToLocal(process_object_ );
}
inline void Environment::set_process_object(v8::Localv8::Object value) {
process_object_ .Reset(isolate(), value);
}
到这里process_object()方法就实现了。那么process对象最后就是这个Evn类的process_object_ 属性。
当然在Evn类的start函数里面把process_object方法指向了其它函数指针就是另外一回事了
nodejs初始化到这里process这个对象来龙去脉基本清楚了,下面就看process对象的属性怎么添加的了,代码如下图
在src/node.cc SetupProcessObject函数里面nodejs初始化添加了众多属性,基本都是通过env类的SetMethod方法,此方法定义如下:
在src/env-inl.h里面nodejs初始化其实最后调用的是process对象的set方法。 process对象是v8::Persistent模版对象set方法调用的是模版Template set方法
nodejs初始化跟到这里基本就差不多明白了,就不再跟了。有兴趣的可以自行跟踪下代码,就是把 name(key) func指针(value)存储到templ list里面.取的时候就根据name来获取函数指针
2.getbinding函数也说下,虽然网上介绍的一大把nodejs初始化builtin优先级最高,会到modlist_builtin中查找,过程非常简单,遍历整个列表,查找相同名字的模块即可。找到后,模块的注册函数会被先执行,然后将数据exports返回。
constants模块优先级次之,Nodejs中的常量定义通过constants导出。
native 优先级最低
//上面一段话从网上找的,说的很明白
js文件通过request函数加载模块,首先会从C++ builtin模块里面找,然后也是从C++里面constants模块找。最后到JS模块找。DefineJavaScript这个函数实现在node_javascript.cc里面,由js2c.py将所有需的JS文件转码实现。具体介绍看如下链接
https://blog.csdn.net/bruk_spp/article/details/92797587
loader.js函数类
nodejs初始化
bootstrapInternalLoaders 这个function由C++调用。参数由C++传过来,实现如下nodejs初始化loaders_bootstrapper就是bootstrapInternalLoaders 的函数指针
nodejs初始化
这里实现调用,将参数对象传给JS使用。第一个就是process,第二个就是Getbinding接口。到这里JS和C++就关联上了
nodej异步io和事件循环是连在一起的,可以说nodejs异步io就是通过事件循环实现的。这个思想在很多项目上都可以看到,实现方式基本大同小异。可能我是做嵌入式的,同步操作效率太低下所以接触到了大量的异步操作。像android系统的广播机制,内核socket异步,定时器伦循。驱动常用的使用poll等待中断,使用select管理套接字等等,这里异步IO就是通过定时器和, 轮循机制实现的。但是所有的异步处理函数都在一个线程里面,当轮循有事件来临就要去停顿处理事件(回调函数)而不能新开一个线程把任务扔出去(像android 里面的使用handle机制把耗时操作扔出主线程),所以如果太耗时操作会明显的影响性能。

相关文章: