当前位置: 首页 > news >正文

Rust有没有信号量机制,在缓存有数据的时候才允许等待的进程取数据?

Rust提供了信号量(Semaphore)机制,尽管它并没有直接提供类似于某些其他编程语言中的Semaphore类。然而,你可以使用std::sync::Mutex和std::sync::Condvar(条件变量)组合来实现信号量的功能。

信号量通常用于控制对共享资源的访问,通过维护一个计数器来限制同时访问资源的线程数。当资源可用时(即缓存中有数据时),等待的线程可以被唤醒并获取资源。

在Rust中,你可以使用Mutex来保护共享资源并提供互斥访问,同时使用Condvar来让等待的线程在条件满足时被唤醒。下面是一个简单的示例,展示了如何使用Mutex和Condvar来实现一个信号量,该信号量允许在缓存有数据时唤醒等待的线程:

use std::sync::{Mutex, Condvar, Arc};  
use std::thread;  
use std::time::Duration;  // 缓存结构  
struct Cache {  data: Mutex<Vec<i32>>,  // 互斥锁保护的数据  not_empty: Condvar,     // 条件变量,用于等待数据可用  not_full: Condvar,      // 条件变量,用于等待空间可用(如果需要的话)  
}  impl Cache {  fn new(capacity: usize) -> Cache {  Cache {  data: Mutex::new(Vec::with_capacity(capacity)),  not_empty: Condvar::new(),  not_full: Condvar::new(),  }  }  // 尝试从缓存中取出数据  fn try_pop(&self) -> Option<i32> {  let mut data = self.data.lock().unwrap();  if data.is_empty() {  None  } else {  Some(data.remove(0))  }  }  // 向缓存中添加数据  fn push(&self, value: i32) {  let mut data = self.data.lock().unwrap();  data.push(value);  self.not_empty.notify_one(); // 通知可能等待的消费者线程  }  // 从缓存中获取数据,如果没有数据则阻塞  fn pop(&self) -> i32 {  let mut data = self.data.lock().unwrap();  while data.is_empty() {  // 等待直到有数据可用或超时  self.not_empty.wait(data.as_mut()).unwrap();  }  data.remove(0)  }  
}  fn main() {  let cache = Arc::new(Cache::new(10)); // 假设缓存容量为10  // 生产者线程  let producer = thread::spawn(move || {  for i in 1..=5 {  thread::sleep(Duration::from_secs(1));  cache.push(i);  println!("Produced: {}", i);  }  });  // 消费者线程  let consumer = thread::spawn(move || {  for _ in 1..=5 {  let value = cache.pop();  println!("Consumed: {}", value);  }  });  // 等待生产者和消费者线程完成  producer.join().unwrap();  consumer.join().unwrap();  
}

在这个示例中,Cache结构体有一个互斥锁data来保护对Vec的访问,以及两个条件变量not_empty和not_full(尽管在这个例子中我们并没有使用not_full,因为我们没有实现缓存满时的等待逻辑)。

pop方法尝试从缓存中取出数据。如果缓存为空,它会调用not_empty.wait(data.as_mut())来阻塞当前线程,同时释放互斥锁,允许其他线程运行。当生产者线程调用push方法并向缓存中添加数据时,它会调用not_empty.notify_one()来唤醒可能正在等待的消费者线程。

这样,我们就实现了一个简单的信号量机制,它允许消费者线程在缓存有数据时获取数据,并在没有数据时等待。

相关文章:

  • 【Go】令牌桶限流算法
  • Unity Text文本实现滚动跑马灯效果
  • (MATLAB)第五章-矩阵运算
  • okHttp MediaType MIME格式详解
  • Java的堆如何分代的?
  • 吴恩达机器学习笔记十六 如何debug一个学习算法 模型评估 模型选择和训练 交叉验证测试集
  • SpringCloudGateway理论与实践
  • 【docker基础学习之】镜像构建
  • VLAN FAQ
  • WiFi模块助力少儿编程:创新学习与实践体验
  • 【kvm企业级虚拟化】之初级篇
  • uniapp直接连接wifi(含有ios和安卓的注意事项)
  • MySQL通过SQL语句进行递归查询
  • python 蓝桥杯之并查集
  • 自动驾驶功能场景 逻辑场景 具体场景解释
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【个人向】《HTTP图解》阅后小结
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • express + mock 让前后台并行开发
  • Fabric架构演变之路
  • LeetCode29.两数相除 JavaScript
  • linux学习笔记
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • Redis的resp协议
  • spring-boot List转Page
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 技术胖1-4季视频复习— (看视频笔记)
  • 前端
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 问题之ssh中Host key verification failed的解决
  • 小试R空间处理新库sf
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • 进程与线程(三)——进程/线程间通信
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # 数论-逆元
  • (1)虚拟机的安装与使用,linux系统安装
  • (C#)一个最简单的链表类
  • (C语言)二分查找 超详细
  • (libusb) usb口自动刷新
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (七)Knockout 创建自定义绑定
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (转)Google的Objective-C编码规范
  • ****Linux下Mysql的安装和配置
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .net开发时的诡异问题,button的onclick事件无效
  • @NoArgsConstructor和@AllArgsConstructor,@Builder
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成