Rust 实现线程安全的 Lock Free 计数器

这篇具有很好参考价值的文章主要介绍了Rust 实现线程安全的 Lock Free 计数器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

完整代码:https://github.com/chiehw/hello_rust/blob/main/crates/counter/src/lib.rs

定义 Trait

Trait 可以看作是一种能力的抽象,和接口有点类似。Trait 还能作为泛型约束条件,作为参数的限制条件。

pub trait AtomicCounter: Send + Sync {
  type PrimitiveType;

  fn get(&self) -> Self::PrimitiveType;	// 获取当前计数器的值。
  fn increase(&self) -> Self::PrimitiveType;	// 自增,并返回上一次的值
  fn add(&self, count: Self::PrimitiveType) -> Self::PrimitiveType;	// 添加一个数,并返回上一次的值
  fn reset(&self) -> Self::PrimitiveType;	// 重置计数器
  fn into_inner(self) -> Self::PrimitiveType;	// 获取内部值
}

简单的测试用例TDD

使用测试驱动开发可以让目标更明确,这里先写个简单的测试案例。

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

  fn test_simple<Counter>(counter: Counter)
  where
    Counter: AtomicCounter<PrimitiveType = usize>,	// 使用 Trait 作为泛型约束条件
  {
    counter.reset();
    assert_eq!(0, counter.add(5));
    assert_eq!(5, counter.increase());
    assert_eq!(6, counter.get())
  }

  #[test]
  fn it_works() {
    test_simple(RelaxedCounter::new(10));
  }
}

亿点细节

直接封装 AtomicUsize

#[derive(Default, Debug)]
pub struct ConsistentCounter(AtomicUsize);

impl ConsistentCounter {
  pub fn new(init_num: usize) -> ConsistentCounter {
    ConsistentCounter(AtomicUsize::new(init_num))
  }
}

impl AtomicCounter for ConsistentCounter {
  type PrimitiveType = usize;

  fn get(&self) -> Self::PrimitiveType {
    self.0.load(Ordering::SeqCst)
  }

  fn increase(&self) -> Self::PrimitiveType {
    self.add(1)
  }

  fn add(&self, count: Self::PrimitiveType) -> Self::PrimitiveType {
    self.0.fetch_add(count, Ordering::SeqCst)
  }

  fn reset(&self) -> Self::PrimitiveType {
    self.0.swap(0, Ordering::SeqCst)
  }

  fn into_inner(self) -> Self::PrimitiveType {
    self.0.into_inner()
  }
}

增加测试用例

使用多线程同时对计数器进行操作,然后判断计数的结果是否正确。更多的测试案例请查看【完整代码】

fn test_increase<Counter>(counter: Arc<Counter>)
  where
    Counter: AtomicCounter<PrimitiveType = usize> + Debug + 'static,
  {
    println!("[+] test_increase: Spawning {} thread, each with {}", NUM_THREADS, NUM_ITERATIONS);
    let mut join_handles = Vec::new();
    // 创建 NUM_THREADS 个线程,同时使用 increase 函数
    for _ in 0..NUM_THREADS {
      let counter_ref = counter.clone();
      join_handles.push(thread::spawn(move || {
        let counter: &Counter = counter_ref.deref();
        for _ in 0..NUM_ITERATIONS {
          counter.increase();
        }
      }));
    }
    // 等待线程完成
    for handle in join_handles {
      handle.join().unwrap();
    }
    let count = Arc::try_unwrap(counter).unwrap().into_inner();
    let excepted_num = NUM_ITERATIONS * NUM_THREADS;
    println!("[+] test_increase: get count {}, excepted num is {}", count, excepted_num);
    // 确定 count 正确
    assert_eq!(count, excepted_num)
  }

参考教程:文章来源地址https://www.toymoban.com/news/detail-849568.html

  • 谈谈 C++ 中的内存顺序 (Memory Order):https://luyuhuang.tech/2022/06/25/cpp-memory-order.html#happens-before

到了这里,关于Rust 实现线程安全的 Lock Free 计数器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA-计数器的实现

    计数器是依托时钟实现的,在时钟沿(一般在上升沿)进行检测,实现计数加1; 计数是从0开始计数的,所以计数值为(M-1),其中M为计数的值。比如计数到10,我们实现时到9即可; 这里为计数器的第一种实现方法,该方法非最优方法,我们只需要了解即可,后续我们会介

    2024年02月04日
    浏览(41)
  • Verilog实现按键计数器

    一、简介 计数器我们都知道,这里我们旨在使用Verilog HDL 来实现按键计数器的操作,功能有: 1、按下一个键,计数加一(+1); 2、按下另一个键,计数减一(-1); 3、按下复位键,则计数清零。 4、最多计数60次。 二、 代码实现 我们使用了两个模块,第一个是按键消抖模

    2024年02月04日
    浏览(49)
  • 计数器简介以及FPGA实现

    在时序逻辑电路中,最基本的单元是寄存器,本篇将会介绍如何利用寄存器,实现一个具有计数器功能的电路。在FPGA开发中,一切与时间有关的设计都会用到计数器,所以学会设计计数器至关重要。 计数是一种最简单基本的运算,计数器就是实现这种运算的逻辑电路,计数

    2024年02月05日
    浏览(55)
  • 【FGPA】Verilog:移位寄存器 | 环形计数器 | 4bit移位寄存器的实现 | 4bit环形计数器的实现

      目录 Ⅰ. 理论部分 0x00 移位寄存器(Shift Register) 0x01 环形计数器(Ring Counter)

    2024年02月05日
    浏览(43)
  • Verilog基础之十、计数器实现

    目录 一、前言 二、工程设计 2.1 设计代码 2.2 综合结果 ​2.3 仿真结果     计数器是较为基础的逻辑,很多其他逻辑可依靠计数器实现,如控制器,分频。原理为通过统计时钟脉冲的个数来输出计数值。 工程设计以计数20的计数器为例 测试代码 综合后的网表可知,6位的计

    2024年02月09日
    浏览(48)
  • FPGA Vivado环境下实现计数器

    本文实现的是一个简单的计数器,模块中包含时钟信号和复位信号,计数使用的是一个四位的输出,复位键有效时,计数器置零,当时钟信号上升沿时,计数加一,实现计数。(仅供参考) 建立工程counter,并新建一个设计文件命名为:counter     3.打开counter文件,进行计数器

    2024年01月21日
    浏览(47)
  • JAVA:基于Redis 实现计数器限流

    1、简述 在现实世界中可能会出现服务器被虚假请求轰炸的情况,因此您可能希望控制这种虚假的请求。 一些实际使用情形可能如下所示: API配额管理-作为提供者,您可能希望根据用户的付款情况限制向服务器发出API请求的速率。这可以在客户端或服务端实现。 安全性-防止

    2024年02月02日
    浏览(42)
  • Verilog语言实现FPGA上的计数器

    Verilog语言实现FPGA上的计数器 计数器是数字电路中经常使用的基本元素之一,它用于生成指定脉冲数量或者指定计数范围内的计数信号。在现代数字电路设计中,FPGA(Field Programmable Gate Array)作为一种可编程逻辑器件被广泛应用,可以通过Verilog语言来实现计数器模块。 在V

    2024年02月05日
    浏览(45)
  • verilog中几种实现计数器的方法

    module counter ( input clk, output reg [3:0] count ); always @(posedge clk) begin if (count == 4’hF) begin count = 4’h0; end else begin count = count + 4’b1; end end endmodule integer      i ; reg [3:0]    counter2 ; initial begin     counter2 = \\\'b0 ;     for (i=0; i=10; i=i+1) begin         #10 ;         counter2 = coun

    2024年02月03日
    浏览(45)
  • 通过verilog实现模可变计数器的设计

    实验要求:          (一) 实验目的 (1)掌握组合逻辑电路和时序电路的 FPGA实现方法; (2)熟悉EDA开发板和开发软件的使用方法; (3)学习静态数码管的使用和7段数码显示译码器设计; (4)掌握时钟在时序电路中的作用; (5)掌握分频电路的实现方法。 (二)

    2024年02月05日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包