Le contenu de cet article est de partager avec vous l'analyse du processus d'explication et d'exécution de node js. Les amis intéressés peuvent y jeter un œil, et les amis dans le besoin peuvent également s'y référer
Explication. : le nœud est monothread, non bloquant, piloté par les événements (similaire aux événements udev dans le noyau, vous pouvez vous référer au mécanisme de rappel d'écoute)
Prenez node-v8.10.0 comme objet, principalement. Documents src/node_main.cc et src/node.cc.
Entrée
node-v8.10.0/src/node_main.cc --> 90 int main(int argc, char *argv[])
Appelez node::Start( argc, argv);
node-v8.10.0/src/node.cc --> 4863 int Start(int argc, char** argv)
a: 4864 atexit([] () { uv_tty_reset_mode( ); });
# Exécuter la fonction anonyme après avoir exécuté *.js, qui exécute en fait uv_tty_reset_mode()
b: 4865 PlatformInit();
# Exécuter la fonction en ligne PlatformInit(), signal Volume enregistrement de la fonction de traitement
c: 4866 node::performance::performance_node_start = PERFORMANCE_NOW();
Encapsuler la fonction uv_hrtime : src/node_perf_common.h:13:#define PERFORMANCE_NOW() uv_hrtime()
Exporter la définition : deps/uv/include/uv.h:1457:UV_EXTERN uint64_t uv_hrtime(void);
Implémentation : deps/uv/src/unix/core.c:111:uint64_t uv_hrtime(void)
uv_hrtime appelle uv__hrtime
Définition : deps/uv/src/unix/internal.h:252:uint64_t uv__hrtime(uv_clocktype_t type);
Implémentation : deps/uv/src/unix/linux-core.c:442:uint64_t uv__hrtime( UV_ClockType_t Type) {
En bref : enregistrez le point temporel de début de l'exécution du nœud*.js script Similaire, enregistrez le point temporel de début du V8 :
4903 node :: performance :: Performance_v8_Start = Performance_now (); d : 4868 CHECK_GT(argc, 0);
src/util.h:129:#define CHECK_GT(a, b) CHECK((a) > (b))
e : 4871 argv = uv_setup_args (argc, argv);
Définition : DEPS/UV/Include/UV.H : 1051 : UV_EXTERN CHAR ** UV_Setup_ARGS (InT ARGC, CHAR ** ARGV); const char**>(argv), &exec_argc, &exec_argv);
4542 void Init(int* argc,
4543 const char** argv,
4544 int* exec_argc,
4545 const char *** exec_argv) {
4617 ProcessArgv(argc, argv, exec_argc, exec_argv);
4502 ParseArgs(arg c, argv, exec_argc, exec_argv, &v8_argc, &v8_argv, is_env);
4015 static void ParseArgs (int* argc,
Paramètres d'analyse
g : configuration associée à openssl
h : 4895 v8_platform.Initialize(v8_thread_pool_size, uv_default_loop());
i : 4902 V8::Initialize ();
initialisation v8
j : 4905 const int exit_code =
4906 Start(uv_default_loop(), argc, argv, exec_argc, exec_argv);
k : Quitter
4908 v8_platform.StopTracingAgent ();
4910 v8_initialized = false;
4911 V8::Dispose();
4919 v8_platform.Dispose();
4921 delete[] exec_argv;
4922 exec_argv = nullptr;
4924 return exit_code ;
2. Analyse de la partie j en 1
a : 4814 inline int Start(uv_loop_t* event_loop,
4815 int argc, const char* const* argv,
4816 int exec_argc, const char* const* exec_argv) {
b: 4824 Isolate* const isolate = Isolate::New(params);
4828 isolate->AddMessageListener(OnMe ssage);
4829 isoler- >SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
4830 isolate->SetAutorunMicrotasks(false);
4831 isolate->SetFatalErrorHandler(OnFatalError);
nouvel Isolat对象,并设置相关参数。
c : 4843 int exit_code;
4844 {
4845 Casier (isoler);
4846 Isolate::Scope isolate_scope(isolat);
4847 HandleScope handle_scope(isolate);
4848 IsolateData isolate_data(isolate , event_loop, allocator.zero_fill_field());
4849 exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv);
4850 }
准备开始执行的参数,isoler对象。
d: 4745 int int Start(Isolate* isolate, IsolateData* isolate_data,
4746 int argc, const char* const* argv,
4747 int exec_argc, const char* const* exec_argv) {
e :环境准备
4748 HandleScope handle_scope(isolate);
4749 Local
4750 Context::Scope context_scope(context);
4751 Environnement env(isolate_data, context);
4754 env.Start(argc, exec_ar, gc, exec_argv , v8_is_profiling);
执行代码 src/env.cc:18:void Environment::Start(int argc,
4771 LoadEnvironment(&env);
加载env
f: 在d中的函数里面进行eventloop,没有event的时候,就会退出node
3. 分析核心部分
4777 {
4778 SealHandleScope seal(isolate);
4779 bool more;
4780 PERFORMANCE_MARK(&env, LOOP_START);
4781 do {
4782 uv_run(env.event_loop(), UV_RUN_DEFAULT);
4783
4784 v8_platform.DrainVMTasks();
4785
4786 more = uv_loop_alive(env.event_loop());
4787 if (more)
4788 continuer;
4789
4790 EmitBeforeExit (&env);
4791
4792 // Émettre ` beforeExit` si la boucle est devenue vivante soit après l'émission
4793 // événement, ou après avoir exécuté quelques rappels.
4794 more = uv_loop_alive(env.event_loop()); // Déterminez à nouveau s'il existe des événements qui n'ont pas été traités. Certaines opérations asynchrones peuvent avoir des fonctions de rappel.
4795 } while (more == true);
4796 PERFORMANCE_MARK(&env, LOOP_EXIT); // S'il n'y a pas de traitement d'événement, quittez.
4797 >
a : La fonction principale uv_run pour le traitement des événements
Déclaration : deps/uv/include/uv.h:281:UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
Implémentation : de PS /uv/src/unix/core.c:348:int uv_run(uv_loop_t* loop, uv_run_mode mode) {
b : Déterminer si la boucle est à l'état actif : s'il y a un handle, un signal de demande et la poignée n'est pas fermée.
343 int uv_loop_alive(const uv_loop_t* boucle) {
344 return uv__loop_alive(loop);
345 }
336 static int uv__loop_alive( const uv_loop_t* boucle) {
337 return uv__has_active_handles(loop ) ||
338 uv__has_active_reqs(loop) ||
339 loop->closing_handles != NULL;
340 }
c: uv__has_active_handles(loop):
deps/uv/src/ uv-common.h:145: #define uv__has_active_handles(loop)
129 #define uv__has_active_reqs(loop) ) == 0)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!