Rust

2025年07月11日更新 6 人订阅
原价: ¥ 2 限时优惠
专栏简介 Rust编程语言之错误处理 Rust 语言之 flod Rust编程语言之Cargo、Crates.io详解 Rust编程语言之枚举与模式匹配 Rust语言 - 接口设计的建议之受约束(Constrained) Rust编程语言之无畏并发 Rust语言 - 接口设计的建议之灵活(flexible) Rust语言 - 接口设计的建议之显而易见(Obvious) Rust语言 - 接口设计的建议之不意外(unsurprising) Rust 实战:构建实用的 CLI 工具 HTTPie Rust编程语言学习之高级特性 Rust内存管理揭秘:深度剖析指针与智能指针 解决Rust中数组和切片的编译时大小问题 《Rust编程之道》学习笔记一 Rust Async 异步编程 简易教程 使用 Async Rust 构建简单的 P2P 节点 Rust编程语言入门之模式匹配 Rust async 编程 Rust编程语言之编写自动化测试 Rust编程语言之函数式语言特性:迭代器和闭包 《Rust编程之道》学习笔记二 Rust Tips 比较数值 使用 Rust 开发一个微型游戏 Rust编程初探:深入理解Struct结构体 深入理解Rust中的内存管理:栈、堆与静态内存详解 深入理解 Rust 结构体:经典结构体、元组结构体和单元结构体的实现 深入掌握 Rust 结构体:从模板到实例化的完整指南 深入理解Rust中的结构体:逻辑与数据结合的实战示例 深入理解 Rust 枚举:从基础到实践 掌握Rust字符串的精髓:String与&str的最佳实践 全面解析 Rust 模块系统:实战案例与应用技巧 Rust 中的 HashMap 实战指南:理解与优化技巧 掌握Rust模式匹配:从基础语法到实际应用 Rust 中的面向对象编程:特性与实现指南 深入理解 Rust 的 Pin 和 Unpin:理论与实践解析 Rust Trait 与 Go Interface:从设计到实战的深度对比 从零开始:用 Rust 和 Axum 打造高效 Web 应用 Rust 错误处理详解:掌握 anyhow、thiserror 和 snafu Rust 如何优雅实现冒泡排序 链表倒数 K 节点怎么删?Python/Go/Rust 实战 用 Rust 玩转数据存储:JSON 文件持久化实战 Rust实战:打造高效字符串分割函数 如何高效学习一门技术:从知到行的飞轮效应 Rust 编程入门:Struct 让代码更优雅 Rust 编程:零基础入门高性能开发 用 Rust 写个猜数游戏,编程小白也能上手! Rust 入门教程:变量到数据类型,轻松掌握! 深入浅出 Rust:函数、控制流与所有权核心特性解析 从零开始:用 Rust 和 Axum 打造高效 Web 服务 Rust 集合类型解析:Vector、String、HashMap 深入浅出Rust:泛型、Trait与生命周期的硬核指南 Rust实战:博物馆门票限流系统设计与实现 用 Rust 打造高性能图片处理服务器:从零开始实现类似 Thumbor 的功能 Rust 编程入门实战:从零开始抓取网页并转换为 Markdown 深入浅出 Rust:高效处理二进制数据的 Bytes 与 BytesMut 实战 Rust智能指针:解锁内存管理的进阶之道 用 Rust 打造命令行利器:从零到一实现 mini-grep 解锁Rust代码组织:轻松掌握Package、Crate与Module Rust 所有权:从内存管理到生产力释放 深入解析 Rust 的面向对象编程:特性、实现与设计模式 Rust + Protobuf:从零打造高效键值存储项目 bacon 点燃 Rust:比 cargo-watch 更爽的开发体验 用 Rust 打造微型游戏:从零开始的 Flappy Dragon 开发之旅 函数式编程的Rust之旅:闭包与迭代器的深入解析与实践 探索Rust编程之道:从设计哲学到内存安全的学习笔记 精读《Rust编程之道》:吃透语言精要,彻底搞懂所有权与借用 Rust 避坑指南:搞定数值比较,别再让 0.1 + 0.2 != 0.3 困扰你! 告别 Vec!掌握 Rust bytes 库,解锁零拷贝的真正威力 告别竞态条件:基于 Axum 和 Serde 的 Rust 并发状态管理最佳实践 Rust 异步编程实践:从 Tokio 基础到阻塞任务处理模式 Rust 网络编程实战:用 Tokio 手写一个迷你 TCP 反向代理 (minginx) 保姆级教程:Zsh + Oh My Zsh 终极配置,让你的 Ubuntu 终端效率倍增 不止于后端:Rust 在 Web 开发中的崛起之路 (2024数据解读) Rust核心利器:枚举(Enum)与模式匹配(Match),告别空指针,写出优雅健壮的代码

Rust实战:博物馆门票限流系统设计与实现

Rust实战:博物馆门票限流系统设计与实现在疫情期间,博物馆等公共场所需要严格控制人流量以确保安全。如何高效实现“满50人后,出来一个才能进一个”的限流机制?本文将通过Rust编程语言,结合Tokio的Semaphore信号量,带你一步步实现一个高并发、线程安全的门票限流系统。无论你是Rust新手

Rust实战:博物馆门票限流系统设计与实现

在疫情期间,博物馆等公共场所需要严格控制人流量以确保安全。如何高效实现“满50人后,出来一个才能进一个”的限流机制?本文将通过Rust编程语言,结合Tokio的Semaphore信号量,带你一步步实现一个高并发、线程安全的门票限流系统。无论你是Rust新手还是并发编程爱好者,这篇实战教程都将为你提供清晰的思路和可运行的代码示例。

本文详细介绍了如何使用Rust和Tokio的Semaphore实现博物馆门票限流系统。文章从问题背景出发,通过代码分步展示了博物馆限流模型的设计与实现,包括依赖配置、核心逻辑、测试用例及运行结果。Semaphore的使用确保了并发安全,而Drop trait的实现则模拟了门票的自动回收机制。文章适合对Rust并发编程或限流场景感兴趣的开发者阅读。

  • Rust实现博物馆门票限流
  • 博物馆门票
  • 疫情期间,博物馆内限流最大容量50人,满了以后,出来一个才能进一个,怎么设计?

Rust实现博物馆门票限流实操

cargo.toml

[package]
name = "training_code"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio = { version = "1.29.1", features = ["sync"] }

lib.rs

pub mod ticket;

ticket.rs

// 博物馆门票
// 疫情期间,博物馆内限流最大容量50人,满了以后,出来一个才能进一个,怎么设计?
// Mutex -> Semaphore
// https://www.cs.brandeis.edu/~cs146a/rust/doc-02-21-2015/nightly/std/sync/struct.Semaphore.html
// https://docs.rs/tokio/latest/tokio/sync/struct.Semaphore.html
use tokio::sync::{Semaphore, SemaphorePermit};

pub struct Museum {
    remaining_tickets: Semaphore,
}

#[derive(Debug)]
pub struct Ticket<'a> {
    permit: SemaphorePermit<'a>,
}

impl<'a> Ticket<'a> {
    pub fn new(permit: SemaphorePermit<'a>) -> Self {
        Self { permit }
    }
}

impl<'a> Drop for Ticket<'a> {
    fn drop(&mut self) {
        println!("ticket freed")
    }
}

impl Museum {
    pub fn new(total: usize) -> Self {
        Self {
            remaining_tickets: Semaphore::new(total),
        }
    }

    pub fn get_ticket(&self) -> Option<Ticket<'_>> {
        // 从信号量中获取许可
        match self.remaining_tickets.try_acquire() {
            Ok(permit) => Some(Ticket::new(permit)),
            Err(_) => None,
        }
    }

    pub fn tickets(&self) -> usize {
        self.remaining_tickets.available_permits() // 返回当前可用许可的数量
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn it_works() {
        let museum = Museum::new(50);
        let ticket = museum.get_ticket().unwrap();
        assert_eq!(museum.tickets(), 49);
        let _tickets: Vec<Ticket> = (0..49).map(|_| museum.get_ticket().unwrap()).collect();
        assert_eq!(museum.tickets(), 0);

        assert!(museum.get_ticket().is_none());

        drop(ticket);
        {
            let ticket = museum.get_ticket().unwrap();
            println!("got ticket: {:?}", ticket);
        }
        println!("!!!!!");
        assert!(museum.get_ticket().is_some());
    }
}

测试

training_code on  master [?] is 📦 0.1.0 via 🦀 1.71.0 via 🅒 base 
➜ cargo test ticket::test::it_works -- --nocapture                                
   Compiling training_code v0.1.0 (/Users/qiaopengjun/Code/rust/training_code)
warning: field `permit` is never read
  --> src/ticket.rs:14:5
   |
13 | pub struct Ticket<'a> {
   |            ------ field in this struct
14 |     permit: SemaphorePermit<'a>,
   |     ^^^^^^
   |
   = note: `Ticket` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
   = note: `#[warn(dead_code)]` on by default

warning: `training_code` (lib test) generated 1 warning
    Finished test [unoptimized + debuginfo] target(s) in 0.94s
     Running unittests src/lib.rs (target/debug/deps/training_code-5f74f464a78aa0d2)

running 1 test
ticket freed
got ticket: Ticket { permit: SemaphorePermit { sem: Semaphore { ll_sem: Semaphore { permits: 0 } }, permits: 1 } }
ticket freed
!!!!!
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
ticket freed
test ticket::test::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s

training_code on  master [?] is 📦 0.1.0 via 🦀 1.71.0 via 🅒 base 
➜ 

总结

通过本文,我们使用Rust和Tokio的Semaphore成功实现了一个博物馆门票限流系统,解决了“最大容量50人,出来一个才能进一个”的需求。Semaphore作为并发控制的利器,结合Rust的内存安全特性,确保了系统的线程安全和高性能。测试结果验证了设计的正确性,Drop trait的自动回收机制也让代码更加优雅。希望这篇教程能为你的Rust并发编程之旅提供启发!欢迎关注我的公众号,获取更多Rust实战内容。

参考

点赞 0
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论