您的位置:首页 > Web前端 > Node.js

node.js源码分析 <一>

2016-08-26 22:18 721 查看


     node.js 无疑是近几年来很火爆到技术,特别是移动互联网的迅速发展 ,node.js的最大特点就是异步单线程 ,有很多优秀的开源框架 比如web 的express

     结合谷歌V8引擎 加载js 实现和底层c代码直接交互,底层用到libuv 这里粗略的分析下node.js模块加载 和 底层事件循环

  

   一、node.cc

  int Start(int argc, char** argv) {

  PlatformInit();

  CHECK_GT(argc, 0);

  // Hack around with the argv pointer. Usedfor process.title = "blah".

  argv = uv_setup_args(argc, argv);

 

 

  // This needs to run *before*V8::Initialize().  The const_cast is not

  // optional, in case you're wondering.

  int exec_argc;

  const char** exec_argv;

  Init(&argc, const_cast<constchar**>(argv), &exec_argc, &exec_argv);

 

 

#if HAVE_OPENSSL

  // V8 on Windows doesn't have a good sourceof entropy. Seed it from

  // OpenSSL's pool.

  V8::SetEntropySource(crypto::EntropySource);

#endif

 

 

  const int thread_pool_size = 4;

  default_platform =v8::platform::CreateDefaultPlatform(thread_pool_size);

  V8::InitializePlatform(default_platform);

  V8::Initialize();

  int exit_code = 1;

  {

    NodeInstanceDatainstance_data(NodeInstanceType::MAIN,

                                  uv_default_loop(),

                                   argc,

                                  const_cast<const char**>(argv),

                                   exec_argc,

                                   exec_argv,

                                  use_debug_agent);

    StartNodeInstance(&instance_data);

    exit_code = instance_data.exit_code();

  }

  V8::Dispose();

  delete default_platform;

  default_platform = nullptr;

  delete[] exec_argv;

  exec_argv = nullptr;

 

 

  return exit_code;

}

   node.cc 里面的start函数是node.js的入口函数 

   PlatformInit(); 做一些初始化的工作 设置信号屏蔽

  const int thread_pool_size = 4;  // 设置线程池大小

default_platform= v8::platform::CreateDefaultPlatform(thread_pool_size);

 V8::InitializePlatform(default_platform);

 V8::Initialize();

  这里是V8里面创建的线程池大小为4

  这个 default_platform  就是后面StartNodeInstance 启动node.js里面的代码

  static void StartNodeInstance(void*arg) 这个函数

  这个函数里面创建一个isolate V8虚拟机 获取堆对象 (js对象)

  里面通过 CreateEnvironment创建js执行环境

  生成一个env

  通过env执行js代码调用底层c函数

  //主进程里面是一个无限循环

   do {

       v8::platform::PumpMessageLoop(default_platform, isolate);

       more = uv_run(env->event_loop(), UV_RUN_ONCE);

       if (more == false) {

         v8::platform::PumpMessageLoop(default_platform, isolate);

         EmitBeforeExit(env);

         // Emit `beforeExit` if the loop became alive either afteremitting

         // event, or after running some callbacks.

         more = uv_loop_alive(env->event_loop());

         if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)

           more = true;

       }

     } while (more == true);

      这里就是整个消息循环

      PumpMessageLoop  调度空闲线程从消息队列里处理等待执行事件

 然后进入uv_run uv_run是libuv里面event loop

    一直循环监听事件 处理事件注册的callback

通过env->event_loop()  返回一个监视器 uv_loop_s 结构体  这里面包括有注册的callback等等

  uv_run都是围绕这个监视器

 具体uv_run里面包括定时器 延时队列  和 优先队列

一些IO耗时任务放到延时队列里面

   

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: