【问题标题】:Synchronization of multiple tasks on single thread在单线程上同步多个任务
【发布时间】:2017-04-07 08:10:10
【问题描述】:

如何防止同一线程重复访问一段代码?

假设,我有下一个代码:

func sendAnalytics() {
    // some synchronous work

    asyncTask() { _ in
        completion()
    }
}

我想在调用完成之前阻止 任何 线程访问“// 一些同步工作”。

objc_sync_enter(self)
objc_sync_exit(self)

似乎只阻止从多个线程访问此代码,而不是让我免于从单个线程访问此代码。有没有办法在不使用自定义解决方案的情况下正确执行此操作?

我的反复访问,我的意思是从一个线程多次调用这个 sendAnalytics。假设,我有一个 for,像这样:

for i in 0...10 {
    sendAnalytics()
}

每个下一个调用都不会在 sendAnalytics 内等待完成(很明显)。在完成触发之前,有没有办法让下一个调用等待?或者整个思维方式是错误的,我必须在 for body 上解决这个问题?

【问题讨论】:

  • 这取决于你是想阻止第二个调用者直到第一个调用完成还是简单地跳过第二个调用
  • 阻止第二个调用者
  • 然后使用初始计数为 0 的 dispatch_semaphore。但是要小心阻塞主队列

标签: ios objective-c multithreading swift3


【解决方案1】:

您可以使用DispatchSemaphore 确保一个呼叫在下一个呼叫开始之前完成

let semaphore = DispatchSemaphore(value:1)

func sendAnalytics() {
    self.semaphore.wait()
    // some synchronous work

    asyncTask() { _ in
        completion()
        self.semaphore.signal()
    }
}

sendAnalytics 的第二次调用将阻塞,直到第一个 asyncTask 完成。您应该注意不要阻塞主队列,因为这会导致您的应用程序变得无响应。将sendAnalytics 调用分派到它自己的串行分派队列中以消除这种风险可能更安全:

let semaphore = DispatchSemaphore(value:1)
let analyticsQueue = DispatchQueue(label:"analyticsQueue")

func sendAnalytics() {
    analyticsQueue.async {
        self.semaphore.wait()
        // some synchronous work

        asyncTask() { _ in
            completion()
            self.semaphore.signal()
        }
     }
}

【讨论】:

  • 对我来说根本没有调用。但它适用于 let semaphore = DispatchSemaphore(value:1)
猜你喜欢
  • 1970-01-01
  • 2017-10-06
  • 2013-12-28
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 2013-04-12
  • 2023-01-31
相关资源
最近更新 更多