简体   繁体   中英

Synchronization of multiple tasks on single thread

How can I prevent a block of code to be repeatedly accessed from the same thread?

Suppose, I have the next code:

func sendAnalytics() {
    // some synchronous work

    asyncTask() { _ in
        completion()
    }
}

I want to prevent any thread from accessing "// some synchronous work", before completion was called.

objc_sync_enter(self)
objc_sync_exit(self)

seem to only prevent accessing this code from multiple threads and don't save me from accessing this code from the single thread. Is there a way to do this correctly, without using custom solutions?

My repeatedly accessing, I mean calling this sendAnalytics from one thread multiple times. Suppose, I have a for, like this:

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

Every next call won't be waiting for completion inside sendAnalytics get called (obvious). Is there a way to make the next calls wait, before completion fires? Or the whole way of thinking is wrong and I have to solve this problem higher, at the for body?

You can use a DispatchSemaphore to ensure that one call completes before the next can start

let semaphore = DispatchSemaphore(value:1)

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

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

The second call to sendAnalytics will block until the first asyncTask is complete. You should be careful not to block the main queue as that will cause your app to become non-responsive. It is probably safer to dispatch the sendAnalytics call onto its own serial dispatch queue to eliminate this risk:

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()
        }
     }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM