Maison > Article > interface Web > Node explique l'analyse du processus d'exécution de js
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!