首页 > 代码库 > 最近看代码的一点总结
最近看代码的一点总结
最近看了些libevent的源码, 发现自己的技术还差的很远。
之前写程序总习惯自己实现。有的东西自己掌握不牢,或者没有接触到新的技术,总是用笨方法写出不好看的代码。之前对TCP/IP,网络编程不是很熟悉,实现的TCP客户端断线重连就很弱。 实现的服务器端监听端口,同时处理多个连接的程序,没有理解清楚one connection one thread的思想,写的代码不够简洁高效。
还是在一次面试中遇到select/poll/epoll相关的问题,之后我才开始在网上以及书上注意到IO多路复用相关的东西。看了不少文档,却没有实际使用过。心里对epoll模型有点畏难的感觉。用过一点select。 最近有机会在网络通信模块中使用epoll实现 事件驱动event loop模型。看了写网上的样例代码,发现使用起来很容易。linux系统库带的功能,接口也比较清晰。
epoll模型的epoll_data结构体的定义很巧妙,通过int和指针的联合变量定义,让使用时既可以直接使用socket fd,也可以自定义结构体。使ptr指向自定义结构体能够提供很好的灵活性,有很多跟事件绑定的东西都可以组织起来,比如回调函数,fd对应客户端的状态变迁等。这样 事件处理的对象就不仅仅是一个IO fd了,可以是fd代表的其他东西。
The struct epoll_event is defined as :
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
最近也看到一个104规约解析的源码mrts,它的数据结构定义的很巧妙,通过定义的struct,避免了频繁的指针强制转换。我之前自己实现的解析程序,主要就是将char类型的报文对应位置强制指针转换来解析的,代码复杂,可读性太差。
/* CP56Time2a timestamp */
typedef struct cp56time2a {
u_short msec;
u_char min :6;
u_char res1 :1;
u_char iv :1;
u_char hour :5;
u_char res2 :2;
u_char su :1;
u_char mday :5;
u_char wday :3;
u_char month :4;
u_char res3 :4;
u_char year :7;
u_char res4 :1;
} cp56time2a __attribute__((__packed__));
/* M_ME_NC_1 - short floating point measured value */
struct iec_type13 {
float mv;
u_char ov :1; /* overflow/no overflow */
u_char res :3;
u_char bl :1; /* blocked/not blocked */
u_char sb :1; /* substituted/not substituted */
u_char nt :1; /* not topical/topical */
u_char iv :1; /* valid/invalid */
}__attribute__((__packed__));
看了点git相关的东西。git和svn的语法还是比较像的,不同的主要是分布式和客户端/服务器模式的区别。另外git的分支branch看起来很有用,有机会一定要试试。
github上有很多不错的源码,配合git,以后阅读源码也方便了。
libevent库中有时间事件的处理,里面提到用小根堆来管理超时时间,时间复杂度O(logn)。libevent用sockpair将 信号的事件处理模型统一到event loop中,相当与将信号处理转化为IO模型。我也是只看了个大概。 之前一直以为 课程上学的堆,动态规划等较复杂的数据结构和算法工作中几乎用不到,现在才知道不是用不到,是自己懒或者畏难。
最近改别人的代码发现 变量命名,数据结构的定义,程序逻辑的设计,代码注释都是很重要的。代码可读性对维护,修改,升级的效率影响很大。同时,工作如果没有责任心,对自己较高的要求,写出的代码往往漏洞百出,只能应付差事。这对于之后的维护是个灾难。 整体的架构,逻辑设计,以及数据结构设计很重要。设计尽量简单高效,层次过多会让人难以理解,通常效率也不会好。
英语很重要。酷壳的陈皓都说英语是计算机工作人员很重要的一项技能。