#mutex #thread #once #rwlock #api-wrapper #behavior

tracing-mutex

通过按顺序分配确保无死锁的互斥锁

5 个不稳定版本

0.3.0 2023年9月13日
0.2.1 2022年5月23日
0.1.2 2021年5月27日

#264并发

Download history 1/week @ 2024-04-17 25/week @ 2024-04-24 81/week @ 2024-05-01 73/week @ 2024-05-08 3/week @ 2024-05-22 134/week @ 2024-05-29 65/week @ 2024-06-05 7/week @ 2024-06-12 34/week @ 2024-06-19 8/week @ 2024-06-26 11/week @ 2024-07-03 28/week @ 2024-07-10 17/week @ 2024-07-17 26/week @ 2024-07-24 20/week @ 2024-07-31

每月 93 次下载
bevy_schedule_dispatch 中使用

MIT/Apache

73KB
1K SLoC

追踪互斥锁

Continuous integration Crates.io Documentation

通过以一致顺序获取它们,或否则,避免互斥锁中的死锁。

背景

在任何使用互斥锁或锁的代码中,你很快就会遇到死锁的可能性。假设有两个互斥锁 FooBar,你就可以已经死锁,前提是一个线程首先锁定 Foo 然后尝试获取 Bar,另一个首先获取 Bar 然后尝试获取 Foo。现在两个线程都在等待对方释放它们已经拥有的锁。

绕过这个问题的简单方法之一是确保当你需要同时获取 FooBar 时,你应该首先获取 Foo,然后你永远不会死锁。当然,对于只有两个互斥锁的情况,这很容易跟踪,但是一旦你的代码开始增长,你可能就会失去对这些依赖的跟踪。这正是这个 crate 的用武之地。

这个 crate 跟踪你在代码中获取锁的顺序,试图根据它构建一个依赖树,如果依赖关系会创建循环,则会引发 panic。它提供了具有相同 API 的现有同步原语的替换方案,应该是一个直接替换。

本 crate 受到 这篇博客文章 的启发,该文章引用了 Abseil 为其互斥锁实现的一种类似行为。这篇文章深入探讨了具体的实现方法。

用法

将此依赖项添加到你的 Cargo.lock 文件中,就像其他任何依赖项一样

[dependencies]
tracing-mutex = "0.2"

然后使用此库提供的锁而不是你通常使用的锁。在 stdsync 模块中可以找到 std::sync 中的同步原语的替换方案。计划支持其他同步原语。

use tracing_mutex::stdsync::Mutex;

let some_mutex = Mutex::new(42);
*some_mutex.lock().unwrap() += 1;
println!("{:?}", some_mutex);

锁之间的相互依赖关系会自动跟踪。如果任何锁定操作会在您的锁之间引入循环依赖,则操作会引发恐慌。这允许您立即发现循环依赖,而不是在生产环境中最终感到惊讶。

互斥锁跟踪是高效的,但它并不是完全没有开销。如果您在生产环境中无法承受性能损失,此库还提供了仅调试跟踪。在 stdsync 模块中也可以找到的 DebugMutex,当启用调试断言时,它评估为 TracingMutex,当未启用时,它评估为 Mutex。还有其他类似的辅助类型可用于其他同步原语。

最低支持的 Rust 版本是 1.70。提高这个版本不被视为破坏性更改,但如果可能,将在与 semver 兼容的版本中避免它。

特性

  • 所有锁定原语的依赖关系跟踪包装器
  • 可选的发布模式代码退出的选项
  • 支持以下原语
    • std::sync
    • parking_lot
    • 任何实现了 lock_api 特性的库

未来改进

  • 改进锁定跟踪的性能
  • 可选的日志记录,以便更容易进行调试
  • 在检测到循环依赖时提供更好的和可配置的错误处理
  • 支持其他锁定库
  • 支持异步锁定库
  • 支持 Send 互斥锁守护者

注意: parking_lot 已经开始开发自己的死锁检测机制,它的工作方式不同。两者可以互补。

许可证

根据您的选择,许可为以下之一

贡献

除非您明确表示否则,您提交的任何贡献,根据 Apache-2.0 许可证定义,均应按上述方式双许可,而无需任何附加条款或条件。

依赖关系

~0–5MB