Skip to content

Instantly share code, notes, and snippets.

@parthjdabhi
Forked from werediver/concurrency.swift
Created July 3, 2017 09:06
Show Gist options
  • Save parthjdabhi/cb6d4b230f64e92bc6550d1111be0cf1 to your computer and use it in GitHub Desktop.
Save parthjdabhi/cb6d4b230f64e92bc6550d1111be0cf1 to your computer and use it in GitHub Desktop.
Limiting concurrent tasks.
import Foundation
func dispatch_async_batch(tasks: [() -> ()], limit: Int, completion: (() -> ())?) {
if tasks.count > 0 || completion != nil {
let q = dispatch_queue_create("dispatch_async_batch", DISPATCH_QUEUE_CONCURRENT);
let sema = dispatch_semaphore_create(limit);
dispatch_async(q, {
for task in tasks {
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
dispatch_async(q, {
task() // The task must be synchronous!
dispatch_semaphore_signal(sema)
})
}
if let completion = completion {
dispatch_barrier_async(q, completion)
}
})
}
}
func dummy(t: NSTimeInterval, _ dt: NSTimeInterval) {
let _t = t + dt * (Double(arc4random()) / Double(UInt32.max) * 2 - 1)
NSThread.sleepForTimeInterval(_t)
}
let tasks = (0 ..< 12).map { i in
return {
print("+ Task #\(i) started")
dummy(4, 2)
print("- Task #\(i) stopped")
}
}
print("Scheduling \(tasks.count) task(s)...")
let sema = dispatch_semaphore_create(1)
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
dispatch_async_batch(tasks, limit: 4) {
print("All tasks has been completed.")
dispatch_semaphore_signal(sema)
}
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER) // Don't let the app terminate until the background work is finished.
/* Sample output
Scheduling 12 task(s)...
+ Task #0 started
+ Task #1 started
+ Task #2 started
+ Task #3 started
- Task #1 stopped
+ Task #4 started
- Task #0 stopped
+ Task #5 started
- Task #2 stopped
+ Task #6 started
- Task #3 stopped
+ Task #7 started
- Task #6 stopped
+ Task #8 started
- Task #4 stopped
+ Task #9 started
- Task #7 stopped
+ Task #10 started
- Task #5 stopped
+ Task #11 started
- Task #8 stopped
- Task #9 stopped
- Task #10 stopped
- Task #11 stopped
All tasks has been completed.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment