Rust
  • Rust语言精简手册
  • Rust中初始化结构体的3种模式
  • Rust中的读写锁RwLock
  • Rust中字符串
Powered by GitBook
On this page
  • 经典问题
  • 基本概念
  • Rust中的读写锁

Was this helpful?

Rust中的读写锁RwLock

本文简单介绍 Rust 中的读写锁RwLock,内容概览如下:

  • 经典问题

    • 读者-作家问题

  • 基本概念

    • 临界区 Critical section

    • 互斥量 Mutex

    • 信号量 Semaphore

    • 读写锁 RWLock

  • RwLock实现

    • std::sync::RwLock

    • parking_lot::RwLock

经典问题

在计算机科学中,有一些经典的同步问题,读者-作家问题就是其中一个,该问题涉及多个并发线程试图同时访问同一共享资源的情况。

读者-作家问题:我们拥有一种资源(例如,数据库),可以由不修改资源的读者和可以修改资源的作家访问。当作家修改资源时,其他任何人(读者或作家)都无法同时访问它,因为另一位作家可能破坏资源,而另一位读者可能读取部分修改的值,因此可能出现不一致。

基本概念

为了准确理解问题,我们先介绍一些基本概念。

临界区 Critical section,在并发编程中,对共享资源的并发访问可能导致意外或错误的行为,因此需要以某种方式保护访问共享资源的那部分程序。这部分受保护的代码片段称为临界区。

互斥量 Mutex,在多线程并发编程时,为了确保一次仅一个线程可以访问共享资源,引入了Mutex的概念,它是 Mutual Exclusion 的缩写,通常翻译为互斥量或互斥锁。

信号量 Semaphore,同样的,为了控制并发系统中多个线程对共享资源的访问,引入了Semaphore的概念,通常翻译为信号量。

读写锁 RWLock,在计算机科学中,读写锁是解决读者-作家问题的同步原语之一。读写锁允许读操作共享访问,而写操作则需要互斥访问。通常构造在互斥量和条件变量之上,或者构造在信号量之上。

Rust中的读写锁

自读者-作家问题提出以来,人们对它进行了广泛的研究,读写锁是解决读者-作家问题的方案之一,按照锁定的锁定的优先级策略分为以下三种:

  • 赋予读者优先权:当前至少有一个读者正在访问资源时,也应允许新读者访问它。如果有作家在等待修改资源并且新的读者一直到来,这可能会导致作家饿死,因为只要有至少一个读者,就永远不会授予作家访问权限。

  • 赋予作家优先权:在这里,读者可能会饿死。

  • 不给予任何优先权:所有读者和作家都将按到达顺序被授予对资源的访问权限。如果在读者访问资源时作家到达,它将等待这些读者释放资源,然后对其进行修改。同时抵达的新读者将不得不等待。

标准库中的RwLock:

  • 允许在任何时间点具有多个读者或最多一个作家。也就是说,RwLock允许任何数量的读者获取锁,只要作家未持有该锁即可。

  • 相比之下,互斥锁不会区分获取锁的种类,因此会阻塞等待可用锁的所有线程。

  • 锁定的优先级策略取决于操作系统的实现,也就是说它不能保证将使用任何特定的优先级策略。

    • Windows和macOS,读者和作家公平排队

    • Linux,读者优先,作家会饿死

use std::sync::RwLock;

let lock = RwLock::new(5);

// many reader locks can be held at once
{
    let r1 = lock.read().unwrap();
    let r2 = lock.read().unwrap();
    assert_eq!(*r1, 5);
    assert_eq!(*r2, 5);
} // read locks are dropped at this point

// only one write lock may be held, however
{
    let mut w = lock.write().unwrap();
    *w += 1;
    assert_eq!(*w, 6);
} // write lock is dropped here

与标准库RwLock的区别:

  • 支持以原子方式将写锁降级为读锁。

  • 公平任务锁定策略,而不是未指定的平台默认值。

  • 没有中毒,该锁通常在出现紧急情况时被释放。

  • 仅需要1个字的空间,而标准库由于平台限制而将RwLock装箱。

  • 可以静态构造(需要const_fn nightly功能)。

    掉落时不需要任何滴胶。

    内联快速路径,适用于无竞争的情况。

    使用自适应旋转有效处理微争用。

    无需保护即可进行原始锁定和解锁。

    支持最终的公平性,因此rwlock平均而言是公平的。

    (可选)通过调用RwLockReadGuard :: unlock_fair和RwLockWriteGuard :: unlock_fair来使rwlock公平。

PreviousRust中初始化结构体的3种模式NextRust中字符串

Last updated 3 years ago

Was this helpful?