33 个版本

使用旧 Rust 2015

0.9.8 2023 年 4 月 3 日
0.9.7 2023 年 3 月 27 日
0.9.5 2023 年 2 月 7 日
0.9.4 2022 年 7 月 14 日
0.1.3 2015 年 1 月 30 日

#2 in 并发

Download history 2042811/week @ 2024-04-29 2002239/week @ 2024-05-06 2190738/week @ 2024-05-13 2157716/week @ 2024-05-20 2149123/week @ 2024-05-27 2348174/week @ 2024-06-03 2297165/week @ 2024-06-10 2237426/week @ 2024-06-17 2227550/week @ 2024-06-24 2023781/week @ 2024-07-01 2219573/week @ 2024-07-08 2236537/week @ 2024-07-15 2314393/week @ 2024-07-22 2261425/week @ 2024-07-29 2251569/week @ 2024-08-05 2233632/week @ 2024-08-12

9,166,102 每月下载量
用于 12,062 个 Crates (279 直接使用)

MIT 许可证

160KB
2.5K SLoC

spin-rs

Crates.io version docs.rs Build Status

基于自旋的同步原语。

此包提供 基于自旋std::sync 中原语的版本。因为同步是通过自旋实现的,所以这些原语适用于在 no_std 环境中使用。

在决定使用 spin 之前,我们建议阅读 这篇优秀的博客文章,由 @matklad 撰写,讨论了自旋锁的优缺点。如果您有访问 std 的权限,那么在非常特定的情况下之外,std::sync 中的原语可能更适合您。

功能

  • MutexRwLockOnceLazyBarrier 的等效功能
  • 支持 no_std 环境
  • lock_api 兼容性
  • 可升级的 RwLock 守护者
  • 守护者可以在线程之间发送和共享
  • 守护者泄漏
  • 票据锁
  • 处理竞争的不同策略

使用

在您的 Cargo.toml 文件的 [dependencies] 部分下包含以下内容。

spin = "x.y"

示例

当在 Mutex 上调用 lock 时,您将获得一个提供数据访问的守护者值。当这个守护者被丢弃时,互斥锁将再次可用。

extern crate spin;
use std::{sync::Arc, thread};

fn main() {
    let counter = Arc::new(spin::Mutex::new(0));

    let thread = thread::spawn({
        let counter = counter.clone();
        move || {
            for _ in 0..100 {
                *counter.lock() += 1;
            }
        }
    });

    for _ in 0..100 {
        *counter.lock() += 1;
    }

    thread.join().unwrap();

    assert_eq!(*counter.lock(), 200);
}

功能标志

此包包含一些您可能希望使用的功能标志。

  • mutex 启用 Mutex 类型。

  • spin_mutex 启用 SpinMutex 类型。

  • ticket_mutex 启用 TicketMutex 类型。

  • use_ticket_mutexMutex 的实现切换为票锁。这仅在普通自旋锁性能非常差的目标上推荐,因为这会改变依赖 spin 的其他 crates 所使用的实现。

  • rwlock 启用 RwLock 类型。

  • once 启用 Once 类型。

  • lazy 启用 Lazy 类型。

  • barrier 启用 Barrier 类型。

  • lock_api 启用对 lock_api 的支持

  • std 启用线程让出而非自旋的支持。

  • portable_atomic 启用使用 portable-atomic crate 的功能以支持没有原生原子操作的平台(Cortex-M0 等)。必须通过最终的二进制 crate 设置 portable_atomic_unsafe_assume_single_core cfg 或 critical-section 特性。

    当使用 cfg 时,可以通过将以下片段适配到 .cargo/config 文件来实现

    [target.<target>]
    rustflags = [ "--cfg", "portable_atomic_unsafe_assume_single_core" ]
    

    请注意,此 cfg 本质上是不可安全的,在多核系统上启用它是不合理的。

    当使用 critical-section 特性时,您需要通过实现一个不安全的 trait 来实现适合您系统的临界区实现。有关更多信息,请参阅 portable-atomic crate 的文档

备注

通常希望锁在多个线程之间共享。通过将锁包装在 std::sync::Arc 中来实现这一点。

通过使用它们的 get_mut 方法,通过可变引用访问时,锁可以提供零开销的数据访问。

这些锁的行为与 std::sync 中的同名对象类似。它们在以下方面有所不同

  • 在失败的情况下,锁不会被污染。
  • 当遇到无法访问的锁时,线程不会向操作系统调度器让出。相反,它们将“自旋”在忙循环中,直到锁变得可用。

上述列出的许多功能标志默认启用。如果您正在编写库,我们建议禁用您不使用的功能,以避免增加您的 crate 用户的编译时间。您可以通过以下方式完成此操作

[dependencies]
spin = { version = "x.y", default-features = false, features = [...] }

最低安全 Rust 版本 (MSRV)

该 crate 保证在最低安全 Rust 版本 (MSRV) 1.38.0 及以上版本上编译。此版本将不会在非次版本号升级的情况下更改。

许可证

spin 根据 MIT 许可证分发(见 LICENSE)。

依赖项

~0–250KB