Skip to content

Instantly share code, notes, and snippets.

@couchdeveloper
Last active March 30, 2016 11:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save couchdeveloper/ca040feec33ab5026ff2 to your computer and use it in GitHub Desktop.
Save couchdeveloper/ca040feec33ab5026ff2 to your computer and use it in GitHub Desktop.
import Foundation
func test(completion: (Int) -> ()) {
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
//let queue = dispatch_queue_create("serial queue", DISPATCH_QUEUE_SERIAL)
var counter = 0
let grp = dispatch_group_create()
for _ in 0..<10000 {
dispatch_group_enter(grp)
dispatch_async(queue) {
counter += 1
dispatch_group_leave(grp)
}
}
dispatch_group_notify(grp, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
completion(counter)
}
}
let sem = dispatch_semaphore_create(0)
test() { counter in
print("counter: \(counter)")
// The counter should be 10000 - unless a data race occurred.
// With a concurrent queue, the variable `counter` is not synchronized and a data race will occure.
dispatch_semaphore_signal(sem)
}
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER)
@qiuyujx
Copy link

qiuyujx commented Mar 29, 2016

Thanks very much for your example. Now I have better understanding of "data race". Based on its definition, I work out a solution by synchronising the counter variable. Do you think this solution actually solved this problem perfectly? Here is my folk https://gist.github.com/qiuyujx/7173ea663308cc03f07e8a5c09cf4cba

@couchdeveloper
Copy link
Author

In my example, simply use the other serial queue, which has been commented out, e.g. use:

//let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let queue = dispatch_queue_create("serial queue", DISPATCH_QUEUE_SERIAL)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment