Rust与Redis数据库开发实战:构建高性能会话管理系统

Rust与Redis数据库开发实战:构建高性能会话管理系统

Rust与Redis数据库开发实战:构建高性能会话管理系统

在这里插入图片描述

一、引言

💡Redis是一款高性能的内存数据库,它支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等,具有读写速度快、内存占用少、跨平台等特点,非常适合开发缓存、消息队列、会话管理、实时数据分析等应用。

Rust语言以其内存安全、高性能和良好的工具链支持,成为开发Redis应用的理想选择。Rust生态系统中提供了多个优秀的Redis库,其中redis-rs是最成熟、最流行的一个。redis-rs提供了安全、易用的API,支持Redis的全部功能,包括事务处理、管道操作、发布订阅等。

二、开发环境搭建

2.1 安装Redis

Redis通常已经预装在大多数操作系统中,你可以通过以下命令检查是否安装:

# 检查Redis版本 redis-cli --version

如果没有安装,可以通过以下命令安装:

macOS
# 使用Homebrew安装 brew install redis # 启动Redis服务 brew services start redis 
Ubuntu/Debian
# 使用apt-get安装sudoapt-get update sudoapt-getinstall-y redis-server # 启动Redis服务sudo systemctl start redis-server 
Windows

下载Redis官方预编译二进制文件:https://github.com/microsoftarchive/redis/releases,解压后将redis-cli.exeredis-server.exe添加到系统路径中。

2.2 创建Rust项目

使用Cargo创建一个新的Rust项目:

# 创建项目cargo new rust-redis-session cd rust-redis-session # 查看项目结构ls-la

2.3 安装redis-rs依赖

Cargo.toml中添加redis-rs依赖:

[package] name = "rust-redis-session" version = "0.1.0" edition = "2021" [dependencies] redis = { version = "0.25", features = ["tokio-comp"] } tokio = { version = "1.0", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uuid = { version = "1.0", features = ["v4"] } chrono = { version = "0.4", features = ["serde"] } thiserror = "1.0" clap = { version = "4.5", features = ["derive"] } 

依赖说明:

  • redis-rs:Redis的Rust绑定,支持异步操作。
  • tokio:Rust的异步运行时。
  • serde:数据序列化/反序列化库。
  • serde_json:JSON数据序列化/反序列化库。
  • uuid:UUID生成库。
  • chrono:日期和时间处理库。
  • thiserror:自定义错误类型库。
  • clap:命令行参数解析库。

三、Redis基本操作

3.1 连接Redis

使用redis-rs连接Redis:

// src/main.rsuseredis::RedisError;usestd::env;asyncfnconnect_redis()->Result<redis::Client,RedisError>{let redis_url =env::var("REDIS_URL").unwrap_or_else(|_|"redis://127.0.0.1:6379".to_string());let client =redis::Client::open(redis_url)?;println!("Successfully connected to Redis");Ok(client)}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;Ok(())}

3.2 字符串操作

使用字符串操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnstring_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 设置值 con.set("username","admin").await?;println!("Successfully set username: admin");// 获取值let username:String= con.get("username").await?;println!("Successfully got username: {}", username);// 设置值并指定过期时间 con.set_ex("token","abc123",3600).await?;println!("Successfully set token: abc123 (expires in 3600 seconds)");// 获取值并检查过期时间let token:Option<String>= con.get("token").await?;ifletSome(token)= token {println!("Successfully got token: {}", token);}else{println!("Token not found");}Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;string_example(&client).await?;Ok(())}

3.3 哈希操作

使用哈希操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnhash_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 设置哈希值 con.hset("user:1","name","admin").await?; con.hset("user:1","email","[email protected]").await?; con.hset("user:1","password","password123").await?;println!("Successfully set user:1");// 获取哈希值let name:String= con.hget("user:1","name").await?;let email:String= con.hget("user:1","email").await?;let password:String= con.hget("user:1","password").await?;println!("Successfully got user:1");println!("Name: {}", name);println!("Email: {}", email);println!("Password: {}", password);// 获取所有哈希字段和值let user:Vec<(String,String)>= con.hgetall("user:1").await?;println!("Successfully got user:1 fields and values: {:?}", user);// 删除哈希字段 con.hdel("user:1","password").await?;println!("Successfully deleted user:1 password");Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;hash_example(&client).await?;Ok(())}

3.4 列表操作

使用列表操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnlist_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 向列表添加元素 con.lpush("tasks","Learn Rust").await?; con.lpush("tasks","Learn Redis").await?; con.lpush("tasks","Build Project").await?;println!("Successfully added tasks to list");// 获取列表长度let length:i64= con.llen("tasks").await?;println!("Tasks list length: {}", length);// 获取列表元素let tasks:Vec<String>= con.lrange("tasks",0,-1).await?;println!("Tasks list: {:?}", tasks);// 从列表左侧弹出元素let task:String= con.lpop("tasks").await?;println!("Successfully popped task from left: {}", task);// 从列表右侧弹出元素let task:String= con.rpop("tasks").await?;println!("Successfully popped task from right: {}", task);Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;list_example(&client).await?;Ok(())}

3.5 集合操作

使用集合操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnset_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 向集合添加元素 con.sadd("tags","Rust").await?; con.sadd("tags","Redis").await?; con.sadd("tags","Web").await?;println!("Successfully added tags to set");// 获取集合元素let tags:Vec<String>= con.smembers("tags").await?;println!("Tags set: {:?}", tags);// 检查元素是否存在let exists:bool= con.sismember("tags","Rust").await?;println!("Tag Rust exists: {}", exists);// 删除元素 con.srem("tags","Web").await?;println!("Successfully removed tag Web from set");Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;set_example(&client).await?;Ok(())}

3.6 有序集合操作

使用有序集合操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnzset_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 向有序集合添加元素 con.zadd("scores","user1",90).await?; con.zadd("scores","user2",85).await?; con.zadd("scores","user3",95).await?;println!("Successfully added scores to zset");// 获取有序集合元素let scores:Vec<(String,i32)>= con.zrange_withscores("scores",0,-1).await?;println!("Scores zset: {:?}", scores);// 获取有序集合元素并按分数降序排序let scores_desc:Vec<(String,i32)>= con.zrevrange_withscores("scores",0,-1).await?;println!("Scores zset (desc): {:?}", scores_desc);// 获取元素的分数let score:i32= con.zscore("scores","user1").await?;println!("User1 score: {}", score);Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;zset_example(&client).await?;Ok(())}

四、实战项目:高性能会话管理系统

4.1 项目概述

开发一个高性能的会话管理系统,支持以下功能:

  • 用户登录:验证用户名和密码
  • 会话创建:创建新的会话
  • 会话验证:验证会话的有效性
  • 会话过期:自动清理过期的会话
  • 会话统计:统计会话数量

4.2 数据结构设计

使用Redis的字符串、哈希、集合等数据结构存储会话数据:

  • 会话ID:使用UUID生成
  • 会话数据:存储在哈希中,包括用户ID、用户名、过期时间等
  • 会话集合:存储所有有效的会话ID
  • 用户会话映射:存储用户ID到会话ID的映射

4.3 代码实现

4.3.1 定义会话结构体
// src/session.rsusechrono::{DateTime,Utc};useserde::{Deserialize,Serialize};useuuid::Uuid;#[derive(Debug, Clone, Serialize, Deserialize)]pubstructSession{pub id:String,pub user_id:String,pub username:String,pub created_at:DateTime<Utc>,pub expires_at:DateTime<Utc>,}implSession{pubfnnew(user_id:String, username:String, expires_in:i64)->Self{let id =Uuid::new_v4().to_string();let created_at =Utc::now();let expires_at = created_at +chrono::Duration::seconds(expires_in);Session{ id, user_id, username, created_at, expires_at,}}pubfnis_expired(&self)->bool{Utc::now()>self.expires_at }}
4.3.2 定义会话管理结构体
// src/session.rsuseredis::AsyncCommands;useredis::RedisError;usestd::collections::HashMap;usecrate::session::Session;#[derive(Debug)]pubstructSessionManager{ client:redis::Client, prefix:String, default_expires_in:i64,}implSessionManager{pubfnnew(client:redis::Client, prefix:String, default_expires_in:i64)->Self{SessionManager{ client, prefix, default_expires_in,}}pubasyncfncreate_session(&self, user_id:String, username:String)->Result<Session,RedisError>{let session =Session::new(user_id, username,self.default_expires_in);letmut con =self.client.get_async_connection().await?;// 存储会话数据let session_key =format!("{}:{}",self.prefix, session.id); con.hset(&session_key,"user_id",&session.user_id).await?; con.hset(&session_key,"username",&session.username).await?; con.hset(&session_key,"created_at",&session.created_at.to_rfc3339()).await?; con.hset(&session_key,"expires_at",&session.expires_at.to_rfc3339()).await?; con.expire(&session_key,self.default_expires_in).await?;println!("Successfully created session: {}", session.id);// 添加到会话集合let sessions_key =format!("{}:sessions",self.prefix); con.sadd(&sessions_key,&session.id).await?;println!("Successfully added session to sessions set: {}", session.id);// 添加到用户会话映射let user_sessions_key =format!("{}:user:{}",self.prefix, session.user_id); con.sadd(&user_sessions_key,&session.id).await?;println!("Successfully added session to user sessions: {}", session.id);Ok(session)}pubasyncfnget_session(&self, session_id:&str)->Result<Option<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;let session_key =format!("{}:{}",self.prefix, session_id);// 获取会话数据let session_data:Option<HashMap<String,String>>= con.hgetall(&session_key).await?;ifletSome(session_data)= session_data {let session =Session{ id: session_id.to_string(), user_id: session_data.get("user_id").unwrap_or(&"".to_string()).to_string(), username: session_data.get("username").unwrap_or(&"".to_string()).to_string(), created_at:DateTime::parse_from_rfc3339(session_data.get("created_at").unwrap_or(&"".to_string())).unwrap().with_timezone(&Utc), expires_at:DateTime::parse_from_rfc3339(session_data.get("expires_at").unwrap_or(&"".to_string())).unwrap().with_timezone(&Utc),};// 检查会话是否过期if session.is_expired(){self.delete_session(session_id).await?;Ok(None)}else{Ok(Some(session))}}else{Ok(None)}}pubasyncfndelete_session(&self, session_id:&str)->Result<(),RedisError>{letmut con =self.client.get_async_connection().await?;let session_key =format!("{}:{}",self.prefix, session_id);// 获取会话数据以删除用户会话映射let session_data:Option<HashMap<String,String>>= con.hgetall(&session_key).await?;ifletSome(session_data)= session_data {let user_id = session_data.get("user_id").unwrap_or(&"".to_string()).to_string();let user_sessions_key =format!("{}:user:{}",self.prefix, user_id); con.srem(&user_sessions_key, session_id).await?;println!("Successfully removed session from user sessions: {}", session_id);}// 删除会话数据 con.del(&session_key).await?;println!("Successfully deleted session data: {}", session_id);// 从会话集合中删除let sessions_key =format!("{}:sessions",self.prefix); con.srem(&sessions_key, session_id).await?;println!("Successfully removed session from sessions set: {}", session_id);Ok(())}pubasyncfnget_user_sessions(&self, user_id:&str)->Result<Vec<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;let user_sessions_key =format!("{}:user:{}",self.prefix, user_id);// 获取用户的所有会话IDlet session_ids:Vec<String>= con.smembers(&user_sessions_key).await?;letmut sessions =Vec::new();// 获取每个会话的数据for session_id in session_ids {ifletSome(session)=self.get_session(&session_id).await?{ sessions.push(session);}}Ok(sessions)}pubasyncfnclean_expired_sessions(&self)->Result<(),RedisError>{letmut con =self.client.get_async_connection().await?;let sessions_key =format!("{}:sessions",self.prefix);// 获取所有会话IDlet session_ids:Vec<String>= con.smembers(&sessions_key).await?;for session_id in session_ids {ifletSome(session)=self.get_session(&session_id).await?{if session.is_expired(){self.delete_session(&session_id).await?;}}}println!("Successfully cleaned expired sessions");Ok(())}}
4.3.3 定义用户认证模块
// src/auth.rsuseserde::{Deserialize,Serialize};#[derive(Debug, Clone, Serialize, Deserialize)]pubstructUser{pub id:String,pub username:String,pub password:String,}implUser{pubfnnew(id:String, username:String, password:String)->Self{User{ id, username, password }}}#[derive(Debug, Clone)]pubstructAuthManager{ users:Vec<User>,}implAuthManager{pubfnnew(users:Vec<User>)->Self{AuthManager{ users }}pubfnauthenticate(&self, username:&str, password:&str)->Option<User>{self.users.iter().find(|user| user.username == username && user.password == password).cloned()}}
4.3.4 定义命令行界面
// src/cli.rsuseclap::Parser;useserde::{Deserialize,Serialize};#[derive(Parser, Debug)]#[command(name = "rust-redis-session")]#[command(about = "A high-performance session management system written in Rust")]structArgs{#[command(subcommand)] command:Commands,}#[derive(clap::Subcommand, Debug)]enumCommands{#[command(about = "User login")]Login{#[arg(short, long, help = "Username")] username:String,#[arg(short, long, help = "Password")] password:String,},#[command(about = "Get session by ID")]Get{#[arg(short, long, help = "Session ID")] session_id:String,},#[command(about = "Delete session by ID")]Delete{#[arg(short, long, help = "Session ID")] session_id:String,},#[command(about = "Get user sessions")]User{#[arg(short, long, help = "User ID")] user_id:String,},#[command(about = "Clean expired sessions")]Clean,}
4.3.5 定义主函数
// src/main.rsuseredis::RedisError;usestd::env;usecrate::auth::AuthManager;usecrate::auth::User;usecrate::cli::Args;usecrate::session::SessionManager;asyncfnconnect_redis()->Result<redis::Client,RedisError>{let redis_url =env::var("REDIS_URL").unwrap_or_else(|_|"redis://127.0.0.1:6379".to_string());let client =redis::Client::open(redis_url)?;println!("Successfully connected to Redis");Ok(client)}asyncfnlogin(session_manager:&SessionManager, auth_manager:&AuthManager, username:&str, password:&str)->Result<(),RedisError>{match auth_manager.authenticate(username, password){Some(user)=>{let session = session_manager.create_session(user.id, user.username).await?;println!("Successfully logged in");println!("Session ID: {}", session.id);println!("Expires at: {}", session.expires_at);}None=>{println!("Invalid username or password");}}Ok(())}asyncfnget_session(session_manager:&SessionManager, session_id:&str)->Result<(),RedisError>{match session_manager.get_session(session_id).await?{Some(session)=>{println!("Successfully got session: {}", session.id);println!("User ID: {}", session.user_id);println!("Username: {}", session.username);println!("Created at: {}", session.created_at);println!("Expires at: {}", session.expires_at);}None=>{println!("Session not found or expired");}}Ok(())}asyncfndelete_session(session_manager:&SessionManager, session_id:&str)->Result<(),RedisError>{ session_manager.delete_session(session_id).await?;println!("Successfully deleted session: {}", session_id);Ok(())}asyncfnget_user_sessions(session_manager:&SessionManager, user_id:&str)->Result<(),RedisError>{let sessions = session_manager.get_user_sessions(user_id).await?;println!("Successfully got user sessions: {}", user_id);for session in sessions {println!("Session ID: {}", session.id);println!("Created at: {}", session.created_at);println!("Expires at: {}", session.expires_at);println!("---");}Ok(())}asyncfnclean_expired_sessions(session_manager:&SessionManager)->Result<(),RedisError>{ session_manager.clean_expired_sessions().await?;Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let args =Args::parse();let client =connect_redis().await?;let session_manager =SessionManager::new(client,"session".to_string(),3600);let users =vec![User::new("1","admin","password123"),User::new("2","user1","password456"),User::new("3","user2","password789"),];let auth_manager =AuthManager::new(users);match args.command {Commands::Login{ username, password }=>{login(&session_manager,&auth_manager,&username,&password).await?;}Commands::Get{ session_id }=>{get_session(&session_manager,&session_id).await?;}Commands::Delete{ session_id }=>{delete_session(&session_manager,&session_id).await?;}Commands::User{ user_id }=>{get_user_sessions(&session_manager,&user_id).await?;}Commands::Clean=>{clean_expired_sessions(&session_manager).await?;}}Ok(())}

4.4 测试项目

运行会话管理系统:

# 编译项目cargo build # 启动Redis服务器(如果未启动) redis-server # 用户登录cargo run -- login --username admin --password password123 # 获取会话cargo run -- get --session-id <session-id># 删除会话cargo run -- delete --session-id <session-id># 获取用户会话cargo run -- user --user-id 1# 清理过期会话cargo run -- clean 

五、性能优化

5.1 使用连接池

使用连接池管理Redis连接:

// src/connection_pool.rsuseredis::RedisError;use r2d2;user2d2_redis::RedisConnectionManager;asyncfncreate_connection_pool()->Result<r2d2::Pool<RedisConnectionManager>,RedisError>{let redis_url =env::var("REDIS_URL").unwrap_or_else(|_|"redis://127.0.0.1:6379".to_string());let manager =RedisConnectionManager::new(redis_url)?;let pool =r2d2::Pool::builder().max_size(10).build(manager)?;println!("Successfully created Redis connection pool");Ok(pool)}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let pool =create_connection_pool().await?;Ok(())}

5.2 使用批量操作

使用批量操作提升性能:

// src/session.rsuseredis::AsyncCommands;useredis::RedisError;usestd::collections::HashMap;implSessionManager{pubasyncfncreate_sessions(&self, users:Vec<(String,String)>)->Result<Vec<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;letmut sessions =Vec::new();for(user_id, username)in users {let session =Session::new(user_id, username,self.default_expires_in);let session_key =format!("{}:{}",self.prefix, session.id); con.hset(&session_key,"user_id",&session.user_id).await?; con.hset(&session_key,"username",&session.username).await?; con.hset(&session_key,"created_at",&session.created_at.to_rfc3339()).await?; con.hset(&session_key,"expires_at",&session.expires_at.to_rfc3339()).await?; con.expire(&session_key,self.default_expires_in).await?;let sessions_key =format!("{}:sessions",self.prefix); con.sadd(&sessions_key,&session.id).await?;let user_sessions_key =format!("{}:user:{}",self.prefix, session.user_id); con.sadd(&user_sessions_key,&session.id).await?; sessions.push(session);}Ok(sessions)}}

5.3 使用管道操作

使用管道操作提升性能:

// src/session.rsuseredis::pipe;useredis::RedisError;implSessionManager{pubasyncfncreate_sessions_pipeline(&self, users:Vec<(String,String)>)->Result<Vec<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;letmut pipe =pipe();letmut sessions =Vec::new();for(user_id, username)in users {let session =Session::new(user_id, username,self.default_expires_in);let session_key =format!("{}:{}",self.prefix, session.id);let sessions_key =format!("{}:sessions",self.prefix);let user_sessions_key =format!("{}:user:{}",self.prefix, session.user_id); pipe .hset(&session_key,"user_id",&session.user_id).ignore().hset(&session_key,"username",&session.username).ignore().hset(&session_key,"created_at",&session.created_at.to_rfc3339()).ignore().hset(&session_key,"expires_at",&session.expires_at.to_rfc3339()).ignore().expire(&session_key,self.default_expires_in).ignore().sadd(&sessions_key,&session.id).ignore().sadd(&user_sessions_key,&session.id).ignore(); sessions.push(session);} pipe.query_async(&mut con).await?;Ok(sessions)}}

5.4 优化缓存策略

使用缓存策略优化性能:

// src/cache.rsuseredis::AsyncCommands;useredis::RedisError;usestd::collections::HashMap;asyncfnoptimize_cache(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 使用set命令代替hset命令 con.set("user:1:name","admin").await?; con.set("user:1:email","[email protected]").await?;println!("Successfully set user data using set commands");// 使用get命令代替hget命令let name:String= con.get("user:1:name").await?;let email:String= con.get("user:1:email").await?;println!("Successfully got user data using get commands: name={}, email={}", name, email);Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;optimize_cache(&client).await?;Ok(())}

六、总结

6.1 技术栈

  • Rust:开发语言
  • redis-rs:Redis的Rust绑定,支持异步操作
  • tokio:Rust的异步运行时
  • serde:数据序列化/反序列化库
  • uuid:UUID生成库
  • chrono:日期和时间处理库
  • thiserror:自定义错误类型库
  • clap:命令行参数解析库

6.2 核心功能

  • 用户登录:验证用户名和密码
  • 会话创建:创建新的会话
  • 会话验证:验证会话的有效性
  • 会话过期:自动清理过期的会话
  • 会话统计:统计会话数量

6.3 未来改进方向

  • 添加会话刷新功能:在会话即将过期时自动刷新会话的过期时间
  • 添加会话统计功能:统计会话的创建时间、过期时间、访问频率等
  • 添加会话限制功能:限制用户的会话数量
  • 添加会话加密功能:对会话数据进行加密存储
  • 添加会话备份功能:定期备份会话数据到磁盘

通过本章的学习,读者可以深入理解Rust与Redis数据库开发的工作原理和实现方法,并在实际项目中应用这些技术。同时,本章也介绍了如何优化Redis操作的性能,帮助读者构建高性能的应用。

Read more

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

摘要:本文聚焦OpenClaw从测试环境走向生产环境的核心痛点,围绕“性能优化、安全加固、监控运维”三大维度展开实操讲解。先明确生产环境硬件/系统选型标准,再通过硬件层资源管控、模型调度策略、缓存优化等手段提升响应速度(实测响应效率提升50%+);接着从网络、权限、数据三层构建安全防护体系,集成火山引擎安全方案拦截高危操作;最后落地TenacitOS可视化监控与Prometheus告警体系,配套完整故障排查清单和虚拟实战案例。全文所有配置、代码均经实测验证,兼顾新手入门实操性和进阶读者的生产级部署需求,帮助开发者真正实现OpenClaw从“能用”到“放心用”的跨越。 优质专栏欢迎订阅! 【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】 【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】 【AI工程化落地与YOLOv8/v9实战】【C#工业上位机高级应用:高并发通信+性能优化】 【Java生产级避坑指南:

By Ne0inhk
ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》 ❄专栏传送门: 《freertos专栏》《STM32 HAL库专栏》 ⭐️流水不争先,争的是滔滔不绝  📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生 | 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生 在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连 目录 前言  一、实验基础说明 1.1、互斥体简介 1.2 本次实验设计思路 二、硬件原理分析(看过之前博客的可以忽略) 三、实验程序编写 3.1 互斥体 LED 驱动代码(mutex.c) 3.2.1、设备结构体定义(28-39

By Ne0inhk
Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 后端工程师扔给你一个 Swagger (OpenAPI) 文档地址,你会怎么做? 1. 对着文档,手写 Dart Model 类(容易写错字段类型)。 2. 手写 Retrofit/Dio 的 API 接口定义(容易拼错 URL)。 3. 当后端修改了字段名,你对着报错修半天。 这是重复劳动的地狱。 swagger_dart_code_generator 可以将 Swagger (JSON/YAML) 文件直接转换为高质量的 Dart 代码,包括: * Model 类:支持 json_serializable,带 fromJson/

By Ne0inhk
Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

文章目录 * 前言 * make/makefile * 文件的三个时间 * Linux第一个小程序-进度条 * 回车和换行 * 缓冲区 * 程序的代码展示 * git指令 * 关于gitee * Linux调试器-gdb使用 * 作业部分 前言 做 Linux 开发时,你是不是也遇到过这些 “卡脖子” 时刻?写 makefile 时,明明语法没错却报错,最后发现是依赖方法行没加 Tab;想提交代码到 gitee,记不清 git add/commit/push 的 “三板斧”,还得反复搜教程;用 gdb 调试程序,输了命令没反应,才想起编译时没加-g生成 debug 版本;甚至连写个进度条,都搞不懂\r和\n的区别,导致进度条乱跳…… 其实这些问题,

By Ne0inhk