Gearmand学习2:main函数

来源:互联网 发布:淘宝刷流量有什么好处 编辑:程序博客网 时间:2024/05/16 14:07

  学习开源的软件,最重要的要找到入口,从入口开始学习是至关重要的,就像一团杂乱无章的线团,只要我们能够找到线头,一切都是那么的简单,而入口main函数就是这团杂乱无章的线头。废话少说,下面我们就从main函数开始学习。
  main函数主要完成以下功能:

  • 完成参数解析
  • 完成插件以及配置的初始化
  • 完成服务启动初始化以及服务启动

参数解析

  这里参数解析采用的是boost库program_options,简介请参考Boost.Program_options简述,专业版请参考Boost.Program_options。参数分成两部分,第一部分是命令行参数,第二部分是配置文件参数(如果命令行中指定了config-file)。

  boost::program_options::options_description all("Allowed options");  //指定通用的配置参数  all.add(general);  //指定HTTP的配置参数  gearmand::protocol::HTTP http;  all.add(http.command_line_options());  //指定gear的配置参数  gearmand::protocol::Gear gear;  all.add(gear.command_line_options());  //指定插件的配置参数  gearmand::plugins::initialize(all);  boost::program_options::positional_options_description positional;  positional.add("provided", -1);  // 指定help参数可见的选项  boost::program_options::options_description visible("Allowed options");  visible.add(all);  //指定用户不可见的选项  boost::program_options::options_description hidden("Hidden options");  hidden.add_options()  ("check-args", boost::program_options::bool_switch(&opt_check_args)->default_value(false),   "Check command line and configuration file argments and then exit.");  all.add(hidden);  //解析命令行配置参数  // Disable allow_guessing  int style= boost::program_options::command_line_style::default_style ^ boost::program_options::command_line_style::allow_guessing;  boost::program_options::parsed_options parsed= boost::program_options::command_line_parser(argc, argv)      .options(all)      .positional(positional)      .style(style)      .run();  store(parsed, vm);  notify(vm);

  当指定了config-file选项时,则会解析配置文件,这里需要注意的是,当配置文件指定的参数和命令行指定的参数重复时,将会以命令行指定的为准。program_options中最先解析的参数将覆盖最后解析的,在程序中先解析命令行参数,后解析配置文件。

std::ifstream ifs(config_file.c_str());if (ifs){    //读取文件内容    std::stringstream ss;    ss << ifs.rdbuf();    //按行拆分,并转换为每个配置    boost::char_separator<char> sep(" \n\r");    std::string sstr= ss.str();    boost::tokenizer<boost::char_separator<char> > tok(sstr, sep);    std::vector<std::string> args;    std::copy(tok.begin(), tok.end(), back_inserter(args));    for (std::vector<std::string>::iterator iter= args.begin();iter != args.end();++iter)    {      std::cerr << *iter << std::endl;    }    //解析配置文件内容    store(boost::program_options::command_line_parser(args).options(visible).run(), vm);}notify(vm);

初始化

//解析日志的级别gearmand_verbose_t verbose= GEARMAND_VERBOSE_ERROR;if (gearmand_verbose_check(verbose_string.c_str(), verbose) == false){  error::message("Invalid value for --verbose supplied");  return EXIT_FAILURE;}if (hashtable_buckets <= 0){  error::message("hashtable-buckets has to be greater than 0");  return EXIT_FAILURE;}if (opt_check_args){  return EXIT_SUCCESS;}//指定帮助信息时,输出相应的帮助信息if (vm.count("help")){  std::cout << visible << std::endl;  return EXIT_SUCCESS;}//输出version信息if (vm.count("version")){  std::cout << std::endl << "gearmand " << gearmand_version() << " - " <<  gearmand_bugreport() << std::endl;  return EXIT_SUCCESS;}//设置能够打开的最大文件描述符个数if (fds > 0 and _set_fdlimit(fds)){  return EXIT_FAILURE;}#当为root时,切换到指定的用户名if (not user.empty() and _switch_user(user.c_str())){  return EXIT_FAILURE;}//启动daemon,后面还需要关闭父进程打开的文件描述符才能完全的完成daemon化if (opt_daemon){  util::daemonize(false, true);}//设置相应的信号处理句柄if (_set_signals(opt_coredump)){  return EXIT_FAILURE;}//记录进程启动的pidutil::Pidfile _pid_file(pid_file);if (_pid_file.create() == false and pid_file.compare(GEARMAND_PID)){  error::perror(_pid_file.error_message().c_str());  return EXIT_FAILURE;}//初始化日志的配置gearmand::gearmand_log_info_st log_info(log_file, opt_syslog);if (log_info.initialized() == false){  return EXIT_FAILURE;}//设置开启的线程数if (threads == 0){  uint32_t number_of_threads= libtest::number_of_cpus();  if (number_of_threads > 4)  {    threads= number_of_threads;  }}

服务初始化及启动

//初始化gearman的配置gearmand_config_st *gearmand_config= gearmand_config_create();if (gearmand_config == NULL){  return EXIT_FAILURE;}//初始化socket选项gearmand_config_sockopt_keepalive(gearmand_config, opt_keepalive);//初始化gearman配置gearmand_st *_gearmand= gearmand_create(gearmand_config,    host.empty() ? NULL : host.c_str(),threads,backlog,  job_handle_prefix.empty()?NULL:job_handle_prefix.c_str(),    static_cast<uint8_t>(worker_wakeup),_log, &log_info,     hashtable_buckets);if (_gearmand == NULL){  error::message("Could not create gearmand library instance.");  return EXIT_FAILURE;}gearmand_config_free(gearmand_config);//初始化插件assert(queue_type.size());if (queue_type.empty() == false){  gearmand_error_t rc;  if ((rc= gearmand::queue::initialize(_gearmand, queue_type.c_str())) != GEARMAND_SUCCESS)  {    error::message("Error while initializing the queue", queue_type.c_str());    gearmand_free(_gearmand);    return EXIT_FAILURE;  }}//初始化gearmanif (gear.start(_gearmand) != GEARMAND_SUCCESS){  error::message("Error while enabling Gear protocol module");  gearmand_free(_gearmand);  return EXIT_FAILURE;}//初始化httpif (protocol.compare("http") == 0){  if (http.start(_gearmand) != GEARMAND_SUCCESS)  {    error::message("Error while enabling protocol module", protocol.c_str());    gearmand_free(_gearmand);    return EXIT_FAILURE;  }}else if (protocol.empty() == false){  error::message("Unknown protocol module", protocol.c_str());  gearmand_free(_gearmand);  return EXIT_FAILURE;}//关闭父进程打开的文件描述符,完成最后的daemonif (opt_daemon){  if (util::daemon_is_ready(true) == false)  {    return EXIT_FAILURE;  }}//开启事件处理线程,正式开始提供服务(死循环)gearmand_error_t ret= gearmand_run(_gearmand);//释放gearman的资源gearmand_free(_gearmand);_gearmand= NULL;

  至此,main函数我们已经学习完毕了,后面我们就跟深入的学习他的插件以及具体的run里面的内容。下面我们先学习插件,了解你其插件的工作模式。

0 0
原创粉丝点击