网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
void redisAppendCommand(redisContext *c, const char *format, ...);
上面的redisAppendCommand函数与redisCommand函数的区别在于,redisAppendCommand函数不返回redis服务器的响应消息(实际上它只将命令放入到output buffer中),而redisCommand函数实际上包括了“redisAppendCommand函数”和“redisGetReply函数”两个步骤,所以redisCommand函数是阻塞的(使用了阻塞的redisContext对象),每次调用redisCommand函数时,都要等待redis服务端的返回结果,然后才能继续执行程序后面的逻辑。
redisCommand函数的使用示例如下:
redisReply *reply;
reply = redisCommand(conn, "SET %s %s", "foo", "bar");
freeReplyObject(reply);
reply = redisCommand(conn, "GET %s", "foo");
printf("%s\n", reply->str);
freeReplyObject(reply);
如果我们需要向redis服务端发送多条命令,如果使用redisCommand函数来发送,那么每次发送后都需要等待返回结果后才能继续下一次发送,这很显然会影响redis客户端的处理性能。
因此,hiredis提供了redisAppendCommand函数,来实现流水线命令发送方案:当我们需要向redis服务端发送多条命令时,可以先调用若干次redisAppendCommand函数,之后,再调用redisGetReply函数来接收(并解析)redis服务器返回的响应消息。
redisAppendCommand函数实现流水线命令方案的示例如下:
redisReply *reply;
redisAppendCommand(context,"SET foo bar");
redisAppendCommand(context,"GET foo");
redisGetReply(context,&reply); // SET命令的返回
freeReplyObject(reply);
redisGetReply(context,&reply); // GET命令的返回
freeReplyObject(reply);
**注意:**redisAppendCommand函数的调用次数必须与redisGetReply函数的调用次数一致,否则会出现获取到的redis服务端返回的处理结果跟预期不一致的情况。示例如下:
// 测试redisGetReply与redisAppendCommand 调用次数不一致的情况
redisAppendCommand(conn, "get foo");
reply = redisCommand(conn, "set fooo barr");
// 此处本想获取set fooo barr的返回信息,却获取了get foo的返回信息
printf("set info: %s\n", reply->str);
上述代码的printf函数打印出来的返回值是“get foo”命令的返回值,因为调用redisAppendCommand函数后,没有与之对应的redisGetReply函数函数调用,后面调用“redisCommand(conn, “set fooo barr”);”时,该函数的子步骤redisGetReply函数会获取input buffer中第一个返回值,即“redisAppendCommand(conn, “get foo”);”的返回值。
2. 流水线客户端示例
2.1 示例代码
redis流水线客户端的示例代码如下:
#include <iostream>
#include "hiredis/hiredis.h"
using namespace std;
int main()
{
// 建立redis连接
redisContext *c = redisConnect("192.168.213.128", 6379);
if ((c == NULL) || (c->err))
{
if (c)
{
cout << "Error: " << c->errstr << endl;
// 释放redis连接
redisFree(c);
return -1;
}
else
{
cout << "Can't allocate redis context." << endl;
return -1;
}
}
else
{
cout << "Connected to Redis." << endl;
}
redisReply *reply;
// 发送添加数据命令、查询数据命令
redisAppendCommand(c, "SET foo bar");
redisAppendCommand(c, "GET foo");
// 获取添加数据命令的返回结果
redisGetReply(c, (void**)&reply);
cout << "SET reply is: " << reply->str << endl;
freeReplyObject(reply);
// 获取查询数据命令的返回结果
redisGetReply(c, (void**)&reply);
cout << "GET reply is: " << reply->str << endl;
freeReplyObject(reply);
// 释放redis连接
redisFree(c);
return 0;
}
2.2 编译redis流水线客户端
执行下面的命令编译上述代码,生成redis客户端:
g++ -o hiredis_syncAPI_pipelining hiredis_syncAPI_pipelining.cpp -lhiredis
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
5%以上C C++开发知识点,真正体系化!**
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新