Redis源码涉及C语言

96
阿飞的博客
2017.09.26 19:24* 字数 1991

sizeof():

太复杂了,泪奔;

void *memcpy(void *dest, const void *src, size_t n);
memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

memset(void *s,int ch,size_t n);

将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。

zmalloc.c中:
#define zmalloc malloc
#define zrealloc realloc
#define zcalloc(x) calloc(x,1)
#define zfree free

malloc:

malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。malloc分配的内存是位于堆中的,并且没有初始化内存的内容(可能有脏数据),因此基本上malloc之后,调用函数memset来初始化这部分的内存空间

calloc:

calloc调用形式为(类型)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址,即在内存中总计申请nsize字节大小的连续地址空间。 calloc会初始化这部分的内存,设置为0;

realloc:

调用形式为 void* realloc(void* ptr, unsigned newsize); realloc的作用给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度

strcasecmp:

函数定义: int strcasecmp (const char *s1, const char *s2);
函数说明 strcasecmp()用来比较参数s1和s2字符串,比较时会自动忽略大小写的差异。
返回结果 若参数s1和s2字符串相等则返回0。s1大于s2则返回大于0 的值,s1 小于s2 则返回小于0的值。

getrlimit&setrlimit:

函数定义:getrlimit(int resource,&limit)
函数说明:获取(getrlimit)&设定(setrlimit)资源使用限制;
struct rlimit limit;
getrlimit(RLIMIT_NOFILE, &limit)
RLIMIT_NOFILE:指定比进程可打开的最大文件描述词大一的值,超出此值,将会产生EMFILE错误。
struct rlimit {
  rlim_t rlim_cur;  //soft limit
  rlim_t rlim_max;  //hard limit
};
rlim_cur是指内核所能支持的资源上限,对应ulimit -n的值;rlim_max对应ulimit -n -H的值;

wait3&wait4:

pid_t wait3 ( int *status, int option, struct rusage *ru );
pid_t wait4 ( pid_t pid, int *status, int option, struct rusage *ru );
wait3等待所有的子进程;
wait4可以像waitpid一样指定要等待的子进程:pid>0表示子进程ID;pid=0表示当前进程组中的子进程;pid=-1表示等待所有子进程;pid<-1表示进程组ID为pid绝对值的子进程。

fork():

fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程, 相当于克隆了一个自己。
在语句fpid=fork()之前,只有一个进程在执行这段代码,但在fork之后,就变成两个进程在执行了,这两个进程的几乎完全相同,将要执行的下一条语句都是if(fpid<0)……
为什么两个进程的fpid不同呢,这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值,我们可以通过fork返回的值来判断当前进程是子进程还是父进程:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
参考:http://www.cnblogs.com/jeakon/archive/2012/05/26/2816828.html

getpid():

定义函数:pid_t getpid(void);
函数说明:getpid ()用来取得目前进程的进程识别码,许多程序利用取到的此值来建立临时文件, 以避免临时文件相同带来的问题 。
范例
#include <unistd.h>
int main()
{
printf("pid=%d\n", getpid());
return 0;
}

snprintf:

函数定义:int snprintf(char *str, size_t size, const char *format, ...);
函数说明:
将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。。
函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。

read&write:

读函数定义: ssize_t read(int fd,void *buf,size_t nbyte)
读函数说明:read函数是负责从fd中读取内容保存到buf中.成功时,read返回实际所读的字节数,如果返回的值是0,表示已经读到文件的结束了.小于0表示出现了错误.

写函数定义:ssize_t write(int fd,const void *buf,size_t nbytes)
写函数说明:write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量. 在网络程序中,当我们向套接字文件描述符写时有俩种可能.
1)write的返回值大于0,表示写了部分或者是全部的数据.
2)返回的值小于0,此时出现了错误.我们要根据错误类型来处理. 如果错误为EINTR表示在写的时候出现了中断错误.
如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接).

ftruncate:

函数定义:int ftruncate(int fd, off_t length)
函数说明:ftruncate()会将参数fd指定的文件大小改为参数length指定的大小。参数fd为已打开的文件描述词,而且必须是以写入模式打开的文件。如果原来的文件件大小比参数length大,则超过的部分会被删去;

fsync与fdatasync:

一般情况下,对硬盘(或者其他持久存储设备)文件的write操作,更新的只是内存中的页缓存(page cache),而脏页面不会立即更新到硬盘中,而是由操作系统统一调度,如由专门的flusher内核线程在满足一定条件时(如一定时间间隔、内存中的脏页达到一定比例)内将脏页面同步到硬盘上(放入设备的IO请求队列)。
因为write调用不会等到硬盘IO完成之后才返回,因此如果OS在write调用之后、硬盘同步之前崩溃,则数据可能丢失。虽然这样的时间窗口很小,但是对于需要保证事务的持久化(durability)和一致性(consistency)的数据库程序来说,write()所提供的“松散的异步语义”是不够的,通常需要OS提供的同步IO(synchronized-IO)原语来保证;
fsync的功能是确保文件fd所有已修改的内容已经正确同步到硬盘上,该调用会阻塞等待直到设备报告IO完成。fdatasync的功能与fsync类似,但是仅仅在必要的情况下才会同步metadata

Redis
Web note ad 1