云度叫车服务器_一看到木头,就有人想要车珠子

都说不要重复造轮子,可是轮子在哪里,怎么才能避免重复造轮子,一般来说优秀的开源代码里大概率有很多可用的轮子。一看到木头,就知道有人要车珠子。看到优秀的开源代码我也忍不住车出珠子来分享给大家。数据库方面Redis肯定拥有姓名,功能性能自不必多说,今天要吹的是它的源码。直接看Redis源码这个项目不算太小,掰开揉碎看清楚不是那么容易。今天给大家介绍一个入门Redis的项目: https://github.com/hurley25/ANet 基于Redis网络模型的简易网络库,网络模块代码取自Redis源码。通过这个小巧的项目一步步走进Redis源码。闲话少叙,盘它。 1、signal // TODO, use sigaction or signalfd
signal(SIGPIPE, SIG_IGN);
main函数第一行,信号的处理,如果对方已经关闭你再往里面写,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。这个信号默认处理方式是进程退出,这里用SIG_IGN忽略这个信号,即程序不退出。signal函数更常用也更易用,看注释信号处理方式还有两种分别是sigaction()和signalfd()后两种是信号处理的高阶阶段了嵌入式方面不常用。signal函数应用程序捕捉(你感兴趣的)特定信号,并作特定的处理。做法也非常简单,在特定信号添加一个回调函数。但是注意哦,并不是你捕捉了特定信号,系统其它部分就不处理了。比如SIGQUIT(Crt+\),虽然你处理了,但是程序仍旧会退出。不同的信号系统的处理结果不同。 2、#include "ae_epoll.c" 这种语法是可以的,只是不常见也不推荐。至于Redis为什么要这样写,大概就是io多路复用不同平台实现方法不同,避免用#ifdef、#elif defined…… 每个#ifdef里面是一大坨代码,代码十分臃肿。处处体现Redis的匠心。 3、zmalloc #define zmalloc malloc  在这个小项目中zmalloc就是malloc,完全满足需求。在Redis中zmalloc.c 被称为是内存管理的基石,处处用的都是自定义的内存管理函数。重新封装的目的一方面是对不同平台的malloc函数进行统一,另一方面更精确更高效地进行内存管理。 4、C语言0长数组
typedef struct {uint32_t magic;uint32_t type;uint32_t length;
} __attribute__((packed)) package_head_t;typedef struct {package_head_t head;unsigned char data[0];
} __attribute__((packed)) package_t;
首先__attribute__属性的作用就是告诉编译器取消结构在编译过程中的优化对齐,告诉编译器你不要瞎搞,只需按照实际占用字节数进行对齐。这样,结构体的长度,就是各个变量长度的和。接下来看package_t的数据部分data[0],使用的时候分配空间大小
package_t *alloc_packet(uint32_t data_len)
{package_t *package = zmalloc(sizeof(package_head_t) + data_len);
    ...return package;
}package_t *package = alloc_packet((uint32_t)strlen(send_buff) + 1);
package->head.type = CHAT_MESSAGE;// copy with '\0'memcpy(package->data, send_buff, strlen(send_buff) + 1);
data[0]数组放在结构体之后,巧妙地实现了C语言的扩展数组。如果使用指针的话需要单独分配一次内存且内存和结构体内存不连续了需要单独管理。这种叫0长数组,还有用1长数组的支持性和兼容性更好。 5、socket封装 anet.c对socket进行了全面的封装,包括客户端和服务端。支持ipv4和ipv6,支持tcp socket和unix socket。 主要函数: anetTcpconnect: anetTcpNonBlockConnect:

创建阻塞/非阻塞连接。socket-->bind(若需要)-->connect,socket创建之后加了anetSetReuseAddr,一般来说,一个端口释放后会等待两分钟之后才能再被使用,这个函数是让端口释放后立即就可以被再次使用,server端需要。

anetRead/anetWrite: 对底层read/write进行封装封装方式非常推荐。 anetTcpServer:

创建监听socket,并调用bind和listen启动服务器开始监听端口。

anetTcpAccept:

调用accept,接收客户端的连接。

其他函数都是辅助,socket可设置参数非常多,常规应用只需要调用封装好的函数即可。 anetRead、anetWrite对于read、write是标准封装,通讯方面都可以借鉴。 6、事件框架 著名的ae事件框架只能另开篇再写,因为实在非常强大又设计精巧。在这个小项目里出现了,只能划出重点,先不解读。 主题教育要求我们学原著读原文悟原理,所以最终还是要在Redis源码里汲取精华。在学懂、弄通、悟透基础上注重做实,亲自动手将源码运用到自己项目中实践才是最终目的。否则, 眼睛说:我会了!手说:不,你不会! 源码的解读有多个层次,多个视角,就像看红楼梦,有的人学习王熙凤的管理艺术,有的人欣赏大观园的雕梁画栋,有的人关注宝黛钗的儿女情长。一个优秀的开源项目可以车的珠子非常多,你需要什么,你的关注点就会落在哪里。好了,第一篇吹水聊天就到这里,Redis深入部分没有涉及,算是抛砖引玉。 帅的人一般点赞分享在看三连,感谢各位!

9f0fa559c8ed1175a22e05c94d38ef27.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值