gflags是Google的一个开源项目,用于解析程序运行参数。gflags简单易用,它的好处在于统一配置格式,减少开发工作量。在工程实践中,gflags在简化开发和测试方面表现非常出色,它还有一个很棒的功能是支持多人合作开发。gflags在2008年首次推出,至今已有10年时间,目前有很多公司都在用gflags。

下面的例子简单展示了C++语言中gflags的基本用法。

#include <iostream>
#include "gflags/gflags.h" // 定义gflags
DEFINE_bool(foo, false, "a simple gflags named foo, default value is flase, wuruilong, 2018-08-16");
DEFINE_int32(thread_num, 10, "thread number, default value is 10, wuruilong, 2018-08-16"); int main(int argc, char **argv) {
// 解析gflags参数,只需要1行代码
google::ParseCommandLineFlags(&argc, &argv, true); // 使用gflags
if (FLAGS_foo) {
std::cout << "foo is true" << std::endl;
} else {
std::cout << "foo is false" << std::endl;
} // 使用gflags
int thread_num = FLAGS_thread_num;
std::cout << "thread number:" << thread_num << std::endl;
return 0;
}

编译:g++ simple_gflags.cpp -I./gflags-2.0/src -L./ -lgflags

运行:

(1)没有参数,./a.out

  1. foo is false
  2. thread number:10

(2)指定参数foo为true,./a.out -foo=true

  1. foo is true
  2. thread number:10

(3)同时指定foo和thread_num,./a.out -foo=true -thread_num=99

  1. foo is true
  2. thread number:99
     
     

上面的例子过于简单,目的是为了消除初学者对gflags的陌生和恐惧感。在工程实践中,有专门定义gflags的文件,通过--flagfile=filename来指定gflags配置文件,其他文件在使用gflags时需要先声明;通常将gflags定义在专门的配置文件中,以方便对程序运行参数管理。

下面是工程实践中使用gflags的例子,新开发的功能用bool类型的gflags包住,新旧代码互不干扰,在gflags开关没有打开时,就好像没有这段代码一样。从这个例子中可以看到gflags在多人开发模式中也能发挥很大的作用。

专门定义gflags的头文件gflags_def.cpp

#include "gflags/gflags.h"

// 定义gflags
DEFINE_bool(add_new_feature_x, false, "x feature, gaojingying, 2018-08-16");
DEFINE_bool(add_new_featrue_y, false, "y feature, xiechao, 2018-08-16");
DEFINE_bool(fix_memory_leak_bug, false, "fix memory leak bug, xiechao, 2018-08-16");
DEFINE_bool(fix_cpu_high_bug, false, "fix cpu high bug, xiechao, 2018-08-16");
DEFINE_int32(thread_pool_worker_num, 10, "thread pool worker number, default value is 10, ligang, 2018-08-16");
DEFINE_string(server_ip, "127.0.0.1", "x server's ip address, gaojingying, 2018-08-16");

其他文件中使用gflags之前,需要先通过DECLARE_声明。

#include <iostream>
#include <string>
#include <cstdio>
#include "gflags/gflags.h" // 声明gflags
DECLARE_bool(add_new_feature_x);
DECLARE_bool(add_new_featrue_y);
DECLARE_bool(fix_memory_leak_bug);
DECLARE_bool(fix_cpu_high_bug);
DECLARE_int32(thread_pool_worker_num);
DECLARE_string(server_ip); void Work(std::string &name) {
name = "feature";
// 启用x功能
if (FLAGS_add_new_feature_x) {
name += "_x";
} // 启用y功能
if (FLAGS_add_new_featrue_y) {
name += "_y";
} char *value = new char[100];
snprintf(value, 100, "thread number: %d", FLAGS_thread_pool_worker_num);
name = name + "," + value + "," + FLAGS_server_ip; // 留下消缺记录
if (FLAGS_fix_memory_leak_bug) {
delete []value;
}
} int main(int argc, char **argv) {
google::ParseCommandLineFlags(&argc, &argv, true); std::string name;
Work(name);
std::cout << name << std::endl;
return 0;
}

编译:g++ main.cpp gflags_def.cpp –I./gflags-2.0/src -L./ -lgflags

gflags配置文件demo_project.gflags

-add_new_feature_x=false
-add_new_featrue_y=true
-fix_memory_leak_bug=true
-fix_cpu_high_bug=false
-thread_pool_worker_num=20
-server_ip="127.0.0.1"

运行:

(1)不指定gflags配置文件,./a.out

feature,thread number: 10,127.0.0.1

(2)指定gflags配置文件,./a.out --flagfile=demo_project.gflags

feature_x,thread number: 20,"127.0.0.1"

有了gflags,测试同学会这样玩:

修改demo_project.gflags,关闭feature_x功能,启用feature_y功能:./a.out --flagfile=demo_project.gflags

feature_y,thread number: 20,"127.0.0.1"

至此,你已经掌握了gflags的基本用法。下面要介绍的内容,有利于全面认识gflags。

A、gflags支持的类型

DEFINE_bool: boolean

DEFINE_int32: 32-bit integer

DEFINE_int64: 64-bit integer

DEFINE_uint64: unsigned 64-bit integer

DEFINE_double: double

DEFINE_string: C++ string

B、gflags的名字空间:DEFINE_XXX和DECLARE_XXX都是全局命名空间。

C、常用的特殊flag

--help             显示所有文件的所有flag,按文件、名称排序,显示flag名、默认值和帮助

--helpshort      只显示执行文件中包含的flag,通常是 main() 所在文件

--version         打印执行文件的版本信息

D、Github上的gflags项目:https://github.com/gflags/gflags

最后要提醒大家的是,金无足赤,人无完人,gflags虽然美妙,但是在使用时也会遇到人们常说的“坑”。下一篇文章中,我将讲述gflags在使用和管理上常见的“坑”,了解这些你将真正获得gflags的使用经验。


金句分享

“很好的事要比糟糕的事好,而糟糕的事要比平庸的事好,因为糟糕的事至少给生活增加了滋味。”

——《原则》,作者瑞·达利欧(Ray Dalio),全球最大对冲基金桥水基金(Bridgewater)创始人

后端系统开发利器之gflags的更多相关文章

  1. Android开发利器之ActivityTracker

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/113 Android开发利器之ActivityTracke ...

  2. 那些年一起用过的iOS开发利器之Parse

    阅读此文章需要对Objective-C和iOS有一定的了解,完全没有基础的朋友请先阅读<让不懂编程的人爱上iPhone开发>系列教程. 什么是后台服务(back-end service)? ...

  3. 那些年一起用过的iOS开发利器之CocoaPods

    本系列所有工具的简介见:http://www.cnblogs.com/lloydsheng/p/3637606.html CocoaPods是一个负责管理iOS项目中第三方开源代码的工具.CocoaP ...

  4. Android开发利器之stetho

    文章同步自javaexception Stetho是什么? github上地址https://github.com/facebook/stetho stetho是facebook出品的一款开发调试工具 ...

  5. Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础

    原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...

  6. Python开发利器之UliPad

    一.安装Ulipad 因为ulipad编辑器使用的是wxpython编写的gui,所以我们需要第三方库wxpython的支持,先讲一下Ulipad在Windows系统环境下的安装: 1. 确实自己的w ...

  7. ionic2——开发利器之Visual Studio Code 常用快捷键

    主命令框 F1 或 Ctrl+Shift+P: 打开命令面板.在打开的输入框内,可以输入任何命令,例如: 按一下 Backspace 会进入到 Ctrl+P 模式 在 Ctrl+P 下输入 >  ...

  8. Android开发利器之pidcat

    介绍pidcat: pidcat 是Android届JakeWharton大神开发的一款命令行工具,堪称Android开发利器,它能方便Android程序猿捕获日志,过滤日志,定位程序问题,超级好用. ...

  9. 那些年一起用过的iOS开发利器之Code Pilot

    本系列所有工具的简介见:http://www.cnblogs.com/lloydsheng/p/3637606.html 什么是Code Pilot? Code Pilot是一个Xcode的扩充套件, ...

随机推荐

  1. QT的QPropertyAnimation讲解

    m_pAnimation->setEasingCurve(QEasingCurve::Linear); //直线风格 m_pAnimation->setLoopCount(-1); //无 ...

  2. TortoiseGit基本操作

    使用之前需要下载git for windows,tortoisegit . 1.TortoiseGit使用与操作 1.1克隆 打开一个要存放项目的文件夹下,右键Git Clone...进行克隆 弹出克 ...

  3. QT信号和槽在哪个线程执行问题

    时隔四个月后的第一篇,换了个公司可以登录的博客,记录一些学习内容吧 这是看到别人写的比较好的一篇,排版有点乱 QThread的使用方法 起源 昨天不小心看到Qt开发人员( Bradley T.Hugh ...

  4. 鉴定JavaScript中的数据类型

    众所周知,JavaScript是一门弱类型的语言,但是这并不代表JavaScript中没有数据类型.JavaScript中常见的数据类型有string.number.object等等,通常我们使用ty ...

  5. JAVA中高访问量高并发的问题怎么解决?

    尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与数据库的交互,提高性能. 用jprofiler等工具找出性能瓶颈,减少额外的开销. 优化数据库查询语句,减少直接使用hiber ...

  6. ListView实现下拉刷新(二)隐藏头布局

    一.问题分析 在上一篇中,我们将头布局加到了ListView上.但是没有隐藏他.你可能会想,隐藏还不简单,直接给它设置为GONE属性不就可以了吗,在需要的时候再设定为可见.没错,这正是ListView ...

  7. 如何理解“Unix 里一切都是文件”这句话-在 UNIX 中,一切都是字节流

    UNIX 操作系统的设计.用户界面.文化和演变都是建立在它的一套统一的想法和概念上.其中最重要的一点可能是“一切皆文件”,而这个概念被认为是 UNIX 的灵魂之一. 这一关键设计原则提供了一个统一的范 ...

  8. 关于SQL注入中编码问题的疑问

    提到SQL注入的绕过,编码是其中最普通的一种方法,最常用的URL编码.之前一直有个疑问,编码与未编码到底有哪些地方存在区别? 以下是本人自己对URL编码的一些见解,可能有错误的地方欢迎大佬们指正. 什 ...

  9. c#类中字段和方法中变量的声明问题

    字段和局部变量的作用域冲突 某些情况下可以区分名称相同,作用域相同的两个标识符.原因是C#在变量之间有一个基本的区分,它把在类级别声明的变量看作 字段,而把在方法中声明的变量看作局部变量. class ...

  10. ssm框架基本流程

    题目,写的有点大了,其实就是 对一张表的基本处理,增删改查的基本操作演示. 好了,我们开始了. 假如,我们在做一个单表处理,就举例是 学院(某个大学的学院) 吧. 首先,我们分析 学校这样表有哪些属性 ...