cmd
是命令的实现函数的数组,命令实现函数的结构如下:
struct redisCommand {
// 命令名称
char *name;
// 命令执行函数
redisCommandProc *proc;
// 参数个数
int arity;
// 字符串表示flag
char *sflags; /* Flags as string representation, one char per flag. */
// 实际flag
int flags; /* The actual flags, obtained from the ‘sflags’ field. */
…
// 指定哪些参数是key
int firstkey; /* The first argument that’s a key (0 = no keys) */
int lastkey; /* The last argument that’s a key */
int keystep; /* The step between first and last key */
// 统计信息
long long microseconds, calls;
};
客户端的创建和关闭
当客户端向服务器发出connect请求的时候,服务器的事件处理器就会对这个事件进行处理,创建相应的客户端状态,并将这个新的客户端状态添加到服务器状态结构clients链表的末尾
/*
* 创建一个新客户端
*/
redisClient *createClient(int fd){
// 分配空间
redisClient *c = zmalloc(sizeof(redisClient));
// 当 fd 不为 -1 时,创建带网络连接的客户端
// 如果 fd 为 -1 ,那么创建无网络连接的伪客户端
// 因为 Redis 的命令必须在客户端的上下文中使用,所以在执行 Lua 环境中的命令时
// 需要用到这种伪终端
if (fd != -1) {
// 非阻塞
anetNonBlock(NULL,fd);
// 禁用 Nagle 算法
anetEnableTcpNoDelay(NULL,fd);
// 设置 keep alive
if (server.tcpkeepalive)
anetKeepAlive(NULL,fd,server.tcpkeepalive);
// 绑定读事件到事件 loop (开始接收命令请求)
if (aeCreateFileEvent(server.el,fd,AE_READABLE,
readQueryFromClient, c) == AE_ERR)
{
close(fd);
zfree©;
return NULL;
}
}
// 初始化各个属性
// 默认数据库
selectDb(c,0);
// 套接字
c->fd = fd;
…
listSetFreeMethod(c->pubsub_patterns,decrRefCountVoid);
listSetMatchMethod(c->pubsub_patterns,listMatchObjects);
// 如果不是伪客户端,那么添加到服务器的客户端链表中
if (fd != -1) listAddNodeTail(server.clients,c);
// 初始化客户端的事务状态
initClientMultiState©;
// 返回客户端
return c;
}
对于客户端的启动程序,其大致的逻辑是:读取本地配置,连接服务器获取服务器的配置,获取本地输入的命令并发送到服务器
一个普通客户端可以因为多种原因而被关闭:
-
如果客户端进程退出或者被杀死,那么客户端与服务器之间的网络连接将被关闭,从而造成客户端被关闭。
-
如果客户端向服务器发送了带有不符合协议格式的命令请求,那么这个客户端也会被服务器关闭。
-
如果客户端成为了CLIENT KLLL命令的目标,那么它也会被关闭。
关闭客户端的底层实现:
/*
* 释放客户端
*/
void freeClient(redisClient *c){
listNode *ln;
…
/* Free the query buffer */
sdsfree(c->querybuf);
c->querybuf = NULL;
/* Deallocate structures used to block on blocking ops. */
if (c->flags & REDIS_BLOCKED) unblockClient©;
dictRelease(c->bpop.keys);
/* UNWATCH all the keys */
// 清空 WATCH 信息
unwatchAllKeys©;
listRelease(c->watched_keys);
/* Unsubscribe from all the pubsub channels */
// 退订所有频道和模式
pubsubUnsubscribeAllChannels(c,0);
pubsubUnsubscribeAllPatterns(c,0);
dictRelease(c->pubsub_channels);
listRelease(c->pubsub_patterns);
/* Close socket, unregister events, and remove list of replies and
* accumulated arguments. */
// 关闭套接字,并从事件处理器中删除该套接字的事件
if (c->fd != -1) {
aeDeleteFileEvent(server.el,c->fd,AE_READABLE);
aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE);
close(c->fd);
}
// 清空回复缓冲区
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数同学面临毕业设计项目选题时,很多人都会感到无从下手,尤其是对于计算机专业的学生来说,选择一个合适的题目尤为重要。因为毕业设计不仅是我们在大学四年学习的一个总结,更是展示自己能力的重要机会。
因此收集整理了一份《2024年计算机毕业设计项目大全》,初衷也很简单,就是希望能够帮助提高效率,同时减轻大家的负担。
既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!
由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频
如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
56)]
[外链图片转存中…(img-oBIjAxeF-1712532665057)]
[外链图片转存中…(img-2ClmXaUz-1712532665058)]
既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!
由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频
如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
[外链图片转存中…(img-8lwko83p-1712532665058)]