c++怎么操作redis数据库_c++ hiredis库连接与命令执行【实战】
技术百科
裘德小鎮的故事
发布时间:2026-01-01
浏览: 次 使用 hiredis 同步连接 Redis 需调用 redisConnectWithTimeout 设置超时(单位为 struct timeval),连接后必须检查 context->err;执行命令需按 redisReply->type 分支安全处理并调用 freeReplyObject 释放;二进制数据须用 redisCommandArgv;context 非线程安全且无自动重连,需手动管理连接与 reply 生命周期。
怎么用 hiredis 连 Redis 服务(同步模式)
hiredis 默认是同步阻塞的,连接失败或网络卡住会直接 hang 住线程。所以第一步必须设好超时,否则生产环境容易出问题。
-
redisConnect不支持超时,得用redisConnectWithTimeout - 超时单位是
struct timeval,不是毫秒——{1, 500000}表示 1.5 秒 - 连接后务必检查
context->err,不能只看指针是否为空(比如认证失败时指针非空但err非零)
struct timeval timeout = {1, 500000};
redisContext *c = redisConnectWithTimeout("127.0.0.1", 6379, timeout);
if (c == nullptr || c->err) {
if (c) {
fprintf(stderr, "Redis connection error: %s\n", c->errstr);
redisFree(c);
}
return -1;
}
怎么执行 SET/GET 命令并安全取返回值
hiredis 的 redisCommand 返回的是 redisReply*,但它的结构不是扁平的,类型判断和字段访问必须严格按 reply->type 分支处理,否则容易段错误或读错内存。
-
REDIS_REPLY_STRING才有str和len;REDIS_REPLY_INTEGER要用integer字段 -
REDIS_REPLY_NIL表示 key 不存在,此时str == nullptr,不能直接strlen - 所有
redisReply*必须用freeReplyObject释放,不释放会内存泄漏
redisReply *reply = (redisReply*)redisCommand(c, "SET mykey 'hello'");
if (reply && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "OK") == 0) {
printf("SET success\n");
}
freeReplyObject(reply);
reply = (redisReply*)redisCommand(c, "GET mykey");
if (reply) {
if (reply->type == REDIS_REPLY_STRING) {
printf("GET result: %.*s\n", (int)reply->len, reply->str);
} else if (reply->type == REDIS_REPLY_NIL) {
printf("key not exists\n");
}
}
freeReplyObject(reply);
怎么处理批量命令和二进制安全数据
Redis 原生支持二进制 key/value,但 C 字符串习惯用 Redis 原生支持二进制 key/value,但 C 字符串习惯用 截断,直接传 \0 截断,直接传 char* 会丢数据。hiredis 提供了带长度参数的接口,必须用它们。char* 会丢数据。hiredis 提供了带长度参数的接口,必须用它们。
- 避免用
redisCommand(c, "SET %b %b", key, key_len, val, val_len)这种格式化方式——它内部仍走 sprintf,对二进制不安全 - 改用
redisCommandArgv,手动构造redisArgv数组,每个元素带len - 批量操作别硬写多个
redisCommand,用 pipeline(即连续发命令+一次收回复)提升吞吐
const char *argv[4]; size_t argvlen[4]; argv[0] = "MSET"; argvlen[0] = 4; argv[1] = "key1"; argvlen[1] = 4; argv[2] = "val1"; argvlen[2] =4; argv[3] = "key2"; argvlen[3] = 4; // 注意:MSET 后面要成对出现,这里只是示意结构 redisReply *r = (redisReply*)redisCommandArgv(c, 4, argv, argvlen);
为什么程序跑一会儿就卡死或崩溃
最常见的三个原因:连接未重连、reply 未释放、多线程共用 context。hiredis 的 redisContext 不是线程安全的,且没有自动重连机制。
- 每次发命令前,检查
c->fd != -1和c->err == 0,任一不成立就得redisFree+ 重连 - 所有
redisCommand调用后,无论成功失败,都必须freeReplyObject(包括返回nullptr的情况) - 多线程场景下,每个线程必须有自己的
redisContext,或者用连接池管理(不能简单全局单例)
连接断开后 redisCommand 可能返回 nullptr,但 context 还活着,继续用会导致未定义行为——这个点最容易被忽略。
# 的是
# 自己的
# 多个
# 用它
# 不存在
# 要用
# 才有
# 就得
# 不支持
# redis
# c++
# 指针
# 字符串
# 接口
# 数据库
# 为什么
# 线程
# red
# 多线程
# Struct
# char
# len
# strlen
# Integer
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 如何在Windows中创建新的用户账户?(标准与管
- php能控制zigbee模块吗_php通过串口与c
- c++中的可变参数模板(variadic temp
- PHP怎么接收前端传的时间戳_处理时间戳参数转换技
- Python与OpenAI接口集成实战_生成式AI
- Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
- VSC怎么在PHP中调试MySQL_数据库交互排查
- Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱
- c++如何利用doxygen生成开发文档_c++
- 如何在 Go 中可靠地测试含 time.Time
- Windows Defender扫描失败怎么办_安
- 如何解决同一段404代码在不同主机上表现不一致的问
- 如何将文本文件中的竖排字符串转换为横排字符串
- 如何使用Golang sort排序切片_Golan
- PHP cURL GET请求:正确设置认证与自定义
- Win11如何设置电源计划_Win11电源计划优化
- Win10怎样清理C盘阿里旺旺缓存_Win10清理
- Win11如何连接Xbox手柄 Win11蓝牙连接
- Windows蓝屏错误0x0000001E怎么修复
- c++怎么操作redis数据库_c++ hired
- LINUX如何查看文件类型_Linux中file命
- Win11 C盘满了怎么清理 Win11磁盘清理和
- Win11怎么开启专注模式_Windows11时钟
- Win11怎么自动隐藏任务栏_Win11全屏显示设
- Win11怎么关闭定位服务 Win11禁止应用获取
- PHP中require语句后直接调用返回对象方法的
- Win11怎么清理C盘OneDrive缓存_Win
- 如何使用Golang实现容器自动化运维_Golan
- Win11键盘快捷键大全_Windows 11常用
- Dapper的Execute方法的返回值是什么意思
- Windows服务启动类型恢复方法_错误修改导致的
- Win11怎么设置组合键快捷方式_Windows1
- Python技术债务管理_长期维护解析【教程】
- MAC怎么一键隐藏桌面所有图标_MAC极简模式切换
- 如何在Golang中实现CI/CD流水线自动化测试
- Linux如何使用Curl发送请求_Linux下A
- Windows 11怎么设置默认解压软件_Wind
- Win10怎么卸载金山毒霸_Win10彻底卸载金山
- php能跑在stm32上吗_php在stm32微控
- php订单日志怎么导出excel_php导出订单日
- Win10系统怎么查看网络连接状态_Windows
- Win11怎么恢复误删照片_Win11数据恢复工具
- 如何在 Go 中判断变量是否为函数类型
- Python配置文件操作教程_JSONINIYAM
- MAC如何启用访达侧边栏显示_MAC Finder
- mac怎么退出id_MAC退出iCloud账号与A
- c# F# 的 MailboxProcessor
- 如何在 Go 中正确测试带 Cookie 的 HT
- c++怎么用jemalloc c++替换默认内存分
- php485能和物联网模块通信吗_php485对接

4;
argv[3] = "key2"; argvlen[3] = 4;
// 注意:MSET 后面要成对出现,这里只是示意结构
redisReply *r = (redisReply*)redisCommandArgv(c, 4, argv, argvlen);
QQ客服