#locking #granular

glock

Rust 的细粒度锁定 crate

3 个版本

使用旧的 Rust 2015

0.1.2 2019年1月3日
0.1.1 2019年1月3日
0.1.0 2019年1月2日

#572 in 并发

每月下载量:21

Apache-2.0

56KB
803

glock

glock 是 Rust 的细粒度锁定 crate。它提供比使用粗粒度的 MutexRwLock 更细粒度的锁定。

GLock 可以是嵌套的或非嵌套的。两种情况下都适用相同的锁定规则,但它们的构造方式不同。

嵌套 GLock

GLock 嵌套(即子 GLock 被父 GLock 保护时),必须使用 GLockBuilder 来构造父 GLock

示例

extern crate glock;

use glock::*;

struct Parent {
    a: GLock<Child>,
    b: GLock<Child>,
}

struct Child {
    x: GLock<i32>,
    y: GLock<i32>,
}

fn main() {
    // Construct parent GLocks and all of its nested GLocks
    let parent_lock = {
        // Prepare parent builder
        let parent_builder = GLock::<Parent>::new_root_builder();

        // Build child GLock protecting first Child struct
        let child1_lock = {
            let child1_builder = parent_builder.new_child_builder().unwrap();

            let child1 = Child {
                x: child1_builder.new_child(0i32).unwrap(),
                y: child1_builder.new_child(0i32).unwrap(),
            };

            child1_builder.build(child1).unwrap()
        };

        // Build child GLock protecting second Child struct
        let child2_lock = {
            let child2_builder = parent_builder.new_child_builder().unwrap();

            let child2 = Child {
                x: child2_builder.new_child(0i32).unwrap(),
                y: child2_builder.new_child(0i32).unwrap(),
            };

            child2_builder.build(child2).unwrap()
        };

        // Create parent struct
        let parent = Parent {
            a: child1_lock,
            b: child2_lock,
        };

        // Build parent GLock protecting parent struct
        parent_builder.build(parent).unwrap()
    };

    // Lock parent
    let p_guard = parent_lock.lock(LockType::IntentionExclusive).unwrap();

    // Lock first child
    let a_guard = p_guard.a.lock_using_parent(LockType::IntentionExclusive, &p_guard).unwrap();

    // Lock and modify field x inside first child
    let mut a_x_guard = a_guard.x.lock_exclusive_using_parent(&a_guard).unwrap();
    *a_x_guard = 10;

    // Lock and modify field y inside first child
    let mut a_y_guard = a_guard.y.lock_exclusive_using_parent(&a_guard).unwrap();
    *a_y_guard = 20;

    // This one will fail with LockError::LockBusy
    let p_guard_2 = parent_lock.try_lock(LockType::Shared).unwrap();
}

非嵌套 GLock

GLock 非嵌套时,可以直接访问子锁。如果您试图获取子 GLock 而不先锁定其父级,则将隐式锁定其父级,并在释放子 GLockGuard 时释放它。

示例

extern crate glock;

use glock::*;

fn main() {
    // Create parent lock
    let parent_lock = GLock::new_root(0u32).unwrap();

    // Create child locks
    let child1_lock = parent_lock.new_child(0u32).unwrap();
    let child2_lock = parent_lock.new_child(0u32).unwrap();

    // An implicit IntentionExclusive lock is acquired on parent_lock,
    // Because child1_lock is a child of parent_lock.
    let mut child1_guard = child1_lock.lock_exclusive().unwrap();
    *child1_guard = 10;

    // This will fail with LockError::LockBusy because an IntentionExclusive lock is held
    // on parent_lock
    let parent_guard2 = parent_lock.try_lock(LockType::Shared).unwrap();
}

无运行时依赖