您的位置:首页 > 教育 > 锐评 > 云商城搭建_成都广告公司简介_如何进行搜索引擎营销_创建网页步骤

云商城搭建_成都广告公司简介_如何进行搜索引擎营销_创建网页步骤

2025/4/29 18:56:50 来源:https://blog.csdn.net/qq8864/article/details/147522098  浏览:    关键词:云商城搭建_成都广告公司简介_如何进行搜索引擎营销_创建网页步骤
云商城搭建_成都广告公司简介_如何进行搜索引擎营销_创建网页步骤

在开发过程中,我们经常会遇到需要在嵌入式Linux系统上与Redis进行交互的需求。因此选择一个适合的Redis客户端库就显得尤为重要。下面介绍下c++中有名的redis-plus-plus(redis++)三方库在嵌入式linux下的交叉编译及使用。该库底层是基于hiredis的良好封装,具备良好的性能。

在C++环境下,hiredishirredisvip是最基础的选择,但它们并没有封装连接池、自动重连等功能,这使得它们在复杂场景中显得力不从心。特别是hiredis,它本身不是线程安全的,每个线程应该维护自己的连接对象,不可在多个线程之间共享一个连接对象。多个线程同时使用同一个连接对象会导致数据竞争和不确定的行为。

还有其他一些库如cloredis,它能够支持集群和单机模式,并且自带连接池功能,但它对Redis哨兵模式的支持并不理想。而redisplus plus这个库,不仅支持Redis的大多数功能,而且提供了更高级的封装和特性,比如自动重连、连接池、哨兵模式等,极大地方便了我们的开发工作。

Redis++介绍

redis++是Redis官网推荐的C++连接库之一,其开源地址为:https://github.com/sewenew/redis-plus-plus。这个库基于hiredis,但提供了更为强大的功能和更好的使用体验。它支持Redis的大多数特性,并对这些特性进行了C++风格的封装,使得在C++项目中使用Redis更加得心应手。

准备交叉编译工具链

在嵌入式Linux开发中,我们通常需要进行交叉编译。这里以ARM和RISC-V架构为例,提供一个配置文件toolchain.cmake,用于设置交叉编译工具链。

# 交叉编译工具链配置文件
# 用于嵌入式Linux系统和RISC-V MCU的交叉编译# 设置系统名称
set(CMAKE_SYSTEM_NAME Linux)# 设置处理器架构变量,可以通过命令行参数传入
# 例如: cmake -DTARGET_ARCH=arm ..
if(NOT DEFINED TARGET_ARCH)set(TARGET_ARCH "arm" CACHE STRING "Target architecture (arm or riscv)")
endif()# 设置ARM工具链路径
set(ARM_TOOLCHAIN_PATH "/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi")
# 设置RISC-V工具链路径
set(RISCV_TOOLCHAIN_PATH "/opt/tronlong/tina5.0_v1.0/rtos/lichee/rtos/tools/riscv64-elf-x86_64-20201104")# 根据目标架构设置主工具链
if(${TARGET_ARCH} STREQUAL "arm")# ARM Linux工具链配置set(CMAKE_C_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-gcc)set(CMAKE_CXX_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-g++)set(CMAKE_FIND_ROOT_PATH /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/)set(CMAKE_SYSTEM_PROCESSOR arm)# 设置额外的编译标志set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfloat-abi=hard -mfpu=neon" CACHE STRING "" FORCE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfloat-abi=hard -mfpu=neon" CACHE STRING "" FORCE)# 设置链接器set(CMAKE_LINKER ${CMAKE_C_COMPILER})set(CMAKE_AR ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-ar)set(CMAKE_RANLIB ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-ranlib)elseif(${TARGET_ARCH} STREQUAL "riscv")# RISC-V工具链配置 (C906核心)set(CMAKE_C_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-gcc)set(CMAKE_CXX_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-g++)set(CMAKE_FIND_ROOT_PATH ${RISCV_TOOLCHAIN_PATH}/riscv64-unknown-elf)set(CMAKE_SYSTEM_PROCESSOR riscv)# 设置RISC-V特定的编译标志 (C906核心)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv64gcv0p7 -mabi=lp64d" CACHE STRING "" FORCE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64gcv0p7 -mabi=lp64d" CACHE STRING "" FORCE)# 设置链接器set(CMAKE_LINKER ${CMAKE_C_COMPILER})set(CMAKE_AR ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ar)set(CMAKE_RANLIB ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ranlib)else()message(FATAL_ERROR "不支持的目标架构: ${TARGET_ARCH}. 请使用 'arm' 或 'riscv'")
endif()# 设置查找规则
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)# 禁用系统库路径
set(CMAKE_SKIP_RPATH TRUE)# 设置交叉编译环境的库和头文件搜索路径
set(CMAKE_SYSROOT ${CMAKE_FIND_ROOT_PATH}) # 关键!!!,不能漏掉这个设置,如果需要安装到特定路径,特别是三方库安装需要到这里找依赖
set(CMAKE_FIND_ROOT_PATH /root/arm_install)

这个配置文件设置了目标系统的名称、处理器架构、工具链路径等重要信息。根据需要,我们可以选择编译针对ARM或RISC-V架构的库文件。

交叉编译Hiredis库

首先,我们需要交叉编译hiredis库,因为redis++是基于hiredis的。在项目根目录下创建一个build目录,并在其中执行以下命令:

cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake -DTARGET_ARCH=arm -DCMAKE_INSTALL_PREFIX=${HOME}/arm_install
make
make install

这样,hiredis库就会被交叉编译并安装到${HOME}/arm_install目录下。

交叉编译Redis++库

接下来,我们使用相同的工具链文件来交叉编译redis++。在redis++的源码目录下创建一个build目录,并在其中执行以下命令:

cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake -DTARGET_ARCH=arm -DCMAKE_INSTALL_PREFIX=${HOME}/arm_install -DCMAKE_PREFIX_PATH=${HOME}/arm_install -DREDIS_PLUS_PLUS_CXX_STANDARD=11 -DREDIS_PLUS_PLUS_BUILD_TEST=OFF
make
make install

这里,我们启用了C++11标准,并且关闭了测试功能,以加快编译速度。编译完成后,redis++库也会被安装到${HOME}/arm_install目录下。

使用Redis++库

下面是一个简单的示例代码,展示了如何使用redis++库。这个示例演示了如何连接到Redis服务器,并进行一些基本的操作,比如读取Hash数据结构中的内容。

#include <unistd.h>
#include <chrono>
#include <tuple>
#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <sw/redis++/redis++.h>
#include <sw/redis++/sentinel.h>
#include <sw/redis++/connection.h>
#include <sw/redis++/connection_pool.h>using namespace sw::redis;
using namespace std::chrono;int main() {// 设置连接选项ConnectionOptions connection_options;connection_options.host = "192.168.11.85";  // 必需,Redis服务器地址connection_options.port = 16379; // 可选,默认端口是6379connection_options.db = 5;  // 可选,默认使用第0个数据库// 设置连接池选项ConnectionPoolOptions pool_options;pool_options.size = 3;  // 连接池大小,即最大连接数pool_options.wait_timeout = std::chrono::milliseconds(100);// 创建Redis连接实例Redis redis(connection_options, pool_options);// 使用hscan命令遍历Hash中的元素auto cursor = 0LL;auto pattern = "*";auto count = 5;std::map<std::string, std::string> hashs;while (true) {cursor = redis.hscan("FORWARD.PLAT.DETAIL", cursor, pattern, count, std::inserter(hashs, hashs.begin()));if (cursor == 0) {break;}}if(hashs.size() < 1) {printf("我们没有获取到任何数据!\n");} else {for(auto it1 = hashs.begin(); it1 != hashs.end(); it1++) {std::cout << "Plat ID:" << it1->first << std::endl;std::cout << "Plat UserName & Password:" << it1->second << std::endl;}}// 使用hget命令获取Hash中指定key的valueOptionalString strValue = redis.hget("XNY.CARINFO", "CRC01211711100232");if (strValue) {std::cout << "CRC01211711100232 的 vin:" << *strValue << std::endl;std::string straa = *strValue;if(straa.empty()) {std::cout << "我们没有获取到任何数据!" << std::endl;} else {std::cout << "---- CRC01211711100232 的 details:" << straa << std::endl;}} else {std::cout << "CRC01211711100232 的 vin 不存在!" << std::endl;}// 使用hincrby命令对Hash中的某个数值字段进行自增操作std::cout << "---- 下面我们来试试hincrby ---- " << std::endl;auto cursor2 = 0LL;auto pattern2 = "*";auto count2 = 20;std::map<std::string, std::string> vv;std::vector<std::string> vlist;while (true) {cursor2 = redis.hscan("FORWARD.LIST.002", cursor2, pattern2, count2, std::inserter(vv, vv.begin()));if (cursor2 == 0) {break;}}for(auto it1 = vv.begin(); it1 != vv.end(); it1++) {vlist.push_back(it1->first);}for(auto uu = vlist.begin(); uu != vlist.end(); uu++) {std::cout << *uu << std::endl;}return 0;
}

在这段代码中,我们首先设置了连接选项和连接池选项,然后创建了一个Redis对象。接着,我们使用hscan命令遍历了一个Hash数据结构中的所有元素,并使用hget命令获取了一个特定key的value。最后,我们尝试使用hincrby命令对一个数值字段进行了自增操作。

结论

通过使用redis++库,我们可以更方便地在嵌入式Linux系统中与Redis进行交互。它提供了丰富的功能和易于使用的接口,极大地方便了开发工作。希望这篇博文能够帮助到需要在嵌入式Linux系统中使用Redis的开发者。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com