SRS启动流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/charles1e/article/details/83624749

main函数

main函数所在文件为main/srs_main_server.cpp中。

该文件定义了一些全局变量:

  • _srs_log:全局的log文件
  • _srs_context:全局的context文件。是一个SrsThreadContext类,这个类使用map来存放协程指针到id的映射关系。std::map<srs_thread_t, int> cache;
  • _srs_config:全局配置文件

执行流程如图:
SRS执行流程

run_master

程序进入run_master。在该函数中,服务器做一些初始化工作并调用listern监听客户端的连接,然后调用do_cycle函数(死循环),做一些监控,更新时间及缓存等。

执行流程如图:

SRS_run_master

代码分析如下:

//run()调用run_master(),启动
srs_error_t run_master(SrsServer* svr)
{
    srs_error_t err = srs_success;
    //初始化st
    if ((err = svr->initialize_st()) != srs_success) {
        return srs_error_wrap(err, "initialize st");
    }
    //初始化signal:创建signal pipe
    if ((err = svr->initialize_signal()) != srs_success) {
        return srs_error_wrap(err, "initialize signal");
    }
    //将pid线程写进文件
    if ((err = svr->acquire_pid_file()) != srs_success) {
        return srs_error_wrap(err, "acquire pid file");
    }
    //监听客户端请求
    if ((err = svr->listen()) != srs_success) {
        return srs_error_wrap(err, "listen");
    }
    //注册信号(开启了新的协程)
    if ((err = svr->register_signal()) != srs_success) {
        return srs_error_wrap(err, "register signal");
    }
    //undo
    if ((err = svr->http_handle()) != srs_success) {
        return srs_error_wrap(err, "http handle");
    }
    //undo
    if ((err = svr->ingest()) != srs_success) {
        return srs_error_wrap(err, "ingest");
    }
    //服务器的循环
    if ((err = svr->cycle()) != srs_success) {
        return srs_error_wrap(err, "main cycle");
    }
    
    return err;
}

do_cycle

srs_error_t SrsServer::do_cycle()
{
    srs_error_t err = srs_success;
    
    // find the max loop
    int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);
    
#ifdef SRS_AUTO_STAT
    max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_DISK_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES);
#endif
    // for asprocess.
    bool asprocess = _srs_config->get_asprocess();
    
    // the deamon thread, update the time cache
    while (true) {
        //这里handle为NULL
        if (handler && (err = handler->on_cycle()) != srs_success) {
            return srs_error_wrap(err, "handle callback");
        }
        
        // the interval in config. default=9.9
        int heartbeat_max_resolution = (int)(_srs_config->get_heartbeat_interval() / SRS_SYS_CYCLE_INTERVAL);
        
        // dynamic fetch the max. 1
        int dynamic_max = srs_max(max, heartbeat_max_resolution);
        
        for (int i = 0; i < dynamic_max; i++) {
            //主线程休眠,让出CPU,其他线程如conn接受连接
            srs_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); //1000 * 1000, 1s
            
            // asprocess check.
            if (asprocess && ::getppid() != ppid) {
                return srs_error_new(ERROR_ASPROCESS_PPID, "asprocess ppid changed from %d to %d", ppid, ::getppid());
            }
            
            // gracefully quit for SIGINT or SIGTERM. 收到腿出信号,返回
            if (signal_gracefully_quit) {
                srs_trace("cleanup for gracefully terminate.");
                return err;
            }
            
            // for gperf heap checker,
            // @see: research/gperftools/heap-checker/heap_checker.cc
            // if user interrupt the program, exit to check mem leak.
            // but, if gperf, use reload to ensure main return normally,
            // because directly exit will cause core-dump.
#ifdef SRS_AUTO_GPERF_MC
            if (signal_gmc_stop) {
                srs_warn("gmc got singal to stop server.");
                return err;
            }
#endif
            
            // do persistence config to file.
            if (signal_persistence_config) {
                signal_persistence_config = false;
                srs_info("get signal to persistence config to file.");
                
                if ((err = _srs_config->persistence()) != srs_success) {
                    return srs_error_wrap(err, "config persistence to file");
                }
                srs_trace("persistence config to file success.");
            }
            
            // do reload the config. 重新加载配置的信号
            if (signal_reload) {
                signal_reload = false;
                srs_info("get signal to reload the config.");
                
                if ((err = _srs_config->reload()) != srs_success) {
                    return srs_error_wrap(err, "config reload");
                }
                srs_trace("reload config success.");
            }
            
            // notice the stream sources to cycle. 流资源循环
            if ((err = SrsSource::cycle_all()) != srs_success) {
                return srs_error_wrap(err, "source cycle");
            }
            
            // update the cache time 事件缓存
            if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) {
                srs_info("update current time cache.");
                srs_update_system_time_ms();
            }
            
#ifdef SRS_AUTO_STAT
            if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) {
                srs_info("update resource info, rss.");
                srs_update_system_rusage();
            }
            if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update cpu info, cpu usage.");
                srs_update_proc_stat();
            }
            if ((i % SRS_SYS_DISK_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update disk info, disk iops.");
                srs_update_disk_stat();
            }
            if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) {
                srs_info("update memory info, usage/free.");
                srs_update_meminfo();
            }
            if ((i % SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES) == 0) {
                srs_info("update platform info, uptime/load.");
                srs_update_platform_info();
            }
            if ((i % SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES) == 0) {
                srs_info("update network devices info.");
                srs_update_network_devices();
            }
            if ((i % SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES) == 0) {
                srs_info("update network server kbps info.");
                resample_kbps();
            }
            if (_srs_config->get_heartbeat_enabled()) {
                if ((i % heartbeat_max_resolution) == 0) {
                    srs_info("do http heartbeat, for internal server to report.");
                    http_heartbeat->heartbeat();
                }
            }
#endif
            
            srs_info("server main thread loop");
        }
    }
    
    return err;
}

猜你喜欢

转载自blog.csdn.net/charles1e/article/details/83624749
srs