libhv源码学习 -- base模块 -- hbase.h

hbase.h

注: 阅读源码时最新代码为 2021年6月更新

  按照官方推荐的源码阅读顺序,就先来看看base模块。
base模块主要目录结构如下:
.
├── array.h 动态数组
├── hatomic.h 原子操作
├── hbase.h 基础函数
├── hbuf.h 缓存
├── hdef.h 常见宏定义
├── heap.h 堆
├── hendian.h 大小端
├── herr.h 错误码表
├── hlog.h 日志
├── hmath.h 数学函数
├── hmutex.h 线程同步锁
├── hplatform.h 平台相关宏
├── hproc.h 进程
├── hsocket.h 套接字
├── hssl.h SSL/TLS
├── hsysinfo.h 系统信息
├── hthread.h 线程
├── htime.h 时间
├── hversion.h 版本
├── list.h 链表
└── queue.h 队列

今天主要研究 hbase.h ,也就是libhv的基础函数。

打开 hbase.h 文件,第一眼便看到引入了3个头文件: hexport.h hplaform.h hdef.h

hexport.hhplaform.h都是一些与平台有关的宏定义,可以大致看一下然后略过,这里主要看一下hdef.h,里面有一些会经常用到的宏定义。
里面包含了一些常见函数,像 取绝对值获取数组大小设置、清除和获取位取最大值、最小值、介于中间的值一些其他宏定义安全分配和释放内存等。
在看分配内存的代码时让我感到惊讶,代码是这样的:

#define SAFE_ALLOC(p, size)\
    do {\
        void* ptr = malloc(size);\
        if (!ptr) {\
            fprintf(stderr, "malloc failed!\n");\
            exit(-1);\
        }                  \
        memset(ptr, 0, size);\
        *(void**)&(p) = ptr;\
    } while(0)
#endif

这是一个宏定义,用于安全分配内存,先使用malloc分配内存,如果失败 exit 退出并输出错误信息,然后使用 memset 初始化,最后赋值给p。主要是这里的 do ... while(0),咋一看感觉是累赘,反正都是执行一次,为什么还要多此一举用循环呢,仔细一像既然这样用就一定有它的道理,便马上打开浏览器搜索了do … while(0)的用处。不看不知道,一看下一跳,原来这样写还有这么多用处!!!

这里结合百度到的说法总结一下 do ... while(0) 的主要作用:

  • 有一个 {}块,可以进行变量定义,实现更复杂功能
  • 结尾没有分号,可以更好衔接上下文(特别是有判断语句的上下文)
  • 消除goto语句,使用break跳出循环

不过我觉得这里最主要的作用是定义一个块,可以定义变量实现更复杂功能,可以使用像使用函数一样使用宏并且不会出错。可以考虑下面的宏定义的使用

#define do_work() work1();work2();
#define safe_do_work() do{work1();work2();}while(0)
. . . 
// 第一种
if (is_work)
	do_work();
// 等价于 -->
if (is_work)
	work1();work1();;

// 第二种
if (is_eork)
	safe_do_work();
// 等价于 -->
if (is_work)
	do{
   work1();work2();}while(0);

这里显然第一种定义不仅不会达到预期效果,还会出现错误。

hbase.h文件里面主要定义了 安全分配和释放内存的函数、C风格字符串操作函数、路径处理函数、以及关于可执行文件路径和目录相关函数。
其中内存分配函数使用了两个全局变量:s_alloc_cnt s_free_cnt
定义如下:

static hatomic_t s_alloc_cnt = HATOMIC_VAR_INIT(0);
static hatomic_t s_free_cnt = HATOMIC_VAR_INIT(0);
...
typedef atomic_long                 hatomic_t;

这两个全局变量为原子类型,用于准确统计内存分配和释放情况:
分配内存时会调用hatomic_inc(&s_alloc_cnt);来增加已分配内存数量
释放内存时会调用hatomic_inc(&s_free_cnt);来增加已释放内存数量
这两个函数也是通过宏定义实现,具体实现会根据不同平台提供不同宏定义,大致如下:

hatomic_inc(&s_alloc_cnt);
hatomic_inc(&
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ticks_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值