Build Status Platforms Matrix

Swift 并发中的锁

这个包暴露了两个类型:AsyncLockAsyncRecursiveLock。它们允许你定义异步临界区。一次只有一个任务可以进入临界区。与传统的锁不同,你可以在持有这些锁的同时安全地进行异步调用。

这是一个处理 Actor 重入的方便工具。

你可能会觉得有用的其他并发包包括 QueueSemaphore

集成

Swift 包管理器

dependencies: [
    .package(url: "https://github.com/mattmassicotte/Lock", branch: "main")
]

用法

这些锁是不可发送(non-Sendable)的。这是一个刻意的选择,不允许跨隔离域共享锁。如果你想这样做,首先要认真思考为什么,然后查看 Semaphore

请注意,尝试获取一个已经被锁定的 AsyncLock 将会导致你的 Actor 死锁。

import Lock

actor MyActor {
  var value = 42
  let lock = AsyncLock()
  let recursiveLock = AsyncRecursiveLock()

  func hasCriticalSections() async {
    // no matter how many tasks call this method,
    // only one will be able to execute at a time
    await lock.lock()

    self.value = await otherObject.getValue()

    lock.unlock()
  }

  func hasCriticalSectionsBlock() async {
    await recursiveLock.withLock {
      // acquiring this multiple times within the same task is safe
      await recursiveLock.withLock {
        self.value = await otherObject.getValue()
      }
    }
  }
}

不幸的是,我还没有完全弄清楚如何正确地实现 AsyncRecursiveLock,所以它目前不是公开的。

贡献和协作

我很乐意听取你的意见!提交 Issue 或 Pull Request 都是很好的方式。 Matrix 空间Discord 也可用于实时帮助,但我强烈倾向于以文档的形式回答问题。

我更喜欢协作,如果你有类似的项目,我很乐意找到合作的方式。

我更喜欢使用制表符进行缩进,以提高可访问性。 但是,我宁愿你使用你喜欢的系统并提交 PR,而不是因为空格而犹豫不决。

通过参与此项目,您同意遵守 贡献者行为准则