gpt4 book ai didi

swift - 同步和异步如何与线程安全一起工作?

转载 作者:行者123 更新时间:2023-11-28 15:19:11 26 4
gpt4 key购买 nike

在 Swift 中,我们可以利用 DispatchQueue 来防止竞争条件。通过使用串行队列,所有事情都按顺序执行,从https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html开始

Serial queues (also known as private dispatch queues) execute one task at a time in the order in which they are added to the queue. The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue. Serial queues are often used to synchronize access to a specific resource.

但是我们很容易造成死锁How do I create a deadlock in Grand Central Dispatch?通过在 async

中执行 sync
let serialQueue = DispatchQueue(label: "Cache.Storage.SerialQueue")
serialQueue.async {
serialQueue.sync {
print("perform some job")
}

print("this can't be reached")
}

防止死锁的唯一方法是使用 2 个串行队列,每个队列用于 syncasync 函数版本。但是当 writeSyncwriteAsync 同时发生时,这可能会导致罕见的情况。

我在 fs module 中看到它同时支持 syncasync 函数,例如 fs.writeFileSync(file, data[, options])fs.writeFile (文件、数据[、选项]、回调)。通过允许这两个版本,是否意味着用户可以按照他们想要的任何顺序使用它们?所以他们很容易像我们上面所做的那样制造死锁?

所以也许 fs 有一个聪明的方法可以应用到 Swift 上?我们如何以线程安全的方式同时支持 syncasync

最佳答案

serialQueue.async {
serialQueue.sync {
print("perform some job")
}
}

之所以会出现死锁,是因为这段代码将第二个任务排入同一个调度队列,然后等待第二个任务完成。然而,第二个任务甚至无法启动,因为它是一个串行队列,而第一个任务仍在执行(尽管在内部信号量上被阻塞)。

避免这种死锁的方法是永远不要那样做。当您认为可以通过以下方式实现相同的效果时,这尤其愚蠢:

serialQueue.async {
print("perform some job")
}

有一些用例可以在与您所在队列不同的队列中运行同步任务,例如

  • 如果另一个队列是主队列,并且您想在继续之前在 UI 中做一些事情
  • 作为不同队列中任务之间同步的一种方式,例如,如果你想确保另一个队列中的所有当前任务在继续之前都已完成。

但是,从来没有理由在同一个队列上同步做某事,你也可以只做某事。或者换句话说,如果你只是一个接一个地写语句,它们已经在同一个队列上同步执行了。

I see in fs module that it supports both sync and async functions, like fs.writeFileSync(file, data[, options]) and fs.writeFile(file, data[, options], callback). By allowing both 2 versions, it means users can use them in any order they want? So they can easily create deadlock like what we did above?

这取决于这两个 API 是如何实现的。调用的同步版本可能只是执行调用而不会影响其他线程。如果它确实捕获了另一个线程,然后等待直到另一个线程完成,那么是的,如果 node.js 服务器用完线程,则可能会出现死锁。

关于swift - 同步和异步如何与线程安全一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46301453/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com