Reputation: 3393
I tried multiple solution/answers given on stackoverflow but none of them worked for me. Some of them is as below :
https://stackoverflow.com/a/30495424/3145189
Is this safe to call wait() of DispatchSemaphore several times at one time?
https://stackoverflow.com/a/37155631/3145189
I am trying to achieve very simple thing, code block or function should execute serially, regardless of from which thread it's been called.
My Example code :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
DispatchQueue.global().async {
self.testLog(name:"first")
}
DispatchQueue.global().async {
self.testLog(name:"second")
}
DispatchQueue.main.async {
self.testLog(name: "mainthread")
}
}
func testLog(name:String) -> Void {
for i in 1..<1000 {
print("thread test \(i) name =\(name)")
}
}
So output should be like -
first thread call
thread test 1 name =first
thread test 2 name =first
thread test 3 name =first
.
.
.
thread test 999 name =first
second thread call
thread test 1 name =second
thread test 2 name =second
.
.
.
thread test 999 name =second
main thread call
thread test 1 name =mainthread
thread test 2 name =mainthread
.
.
.
thread test 999 name =mainthread
If function is called on first thread, it should continue print log for the first thread only. Order of thread can vary I don't care means even if it's print mainthread log first then second and first doesn't matter logs should be grouped.
Upvotes: 1
Views: 3462
Reputation: 53000
I am trying to achieve very simple thing, code block or function should execute serially, regardless of from which thread it's been called.
To execute serially you use a Dispatch serial queue. If you were writing a class or struct you could use a static let
at class/struct level to store your queue in which your serialising function could dispatch to. A static let
in this case is equivalent to a "class variable" in some languages.
If you were writing in (Objective-)C such variables can also be declared at the function level, that is a variable with global lifetime but with scope limited to within the function. Swift does not support these within a function, but you can scope a struct to a function...
func testLog(name:String) -> Void
{
struct LocalStatics
{
static let privateQueue = DispatchQueue(label: "testLogQueue")
}
// run the function body on the serial queue - could use async here
// and the body would still run not interleaved with other calls but
// the caller need not wait for it to do so
LocalStatics.privateQueue.sync {
for i in 1..<1000
{
print("thread test \(i) name =\(name)")
}
}
}
(For a debate on "local statics" in Swift see this SO Q&A)
Upvotes: 0
Reputation: 1559
This will execute the calls serially.
Keep a reference to serialQueue
and you can submit blocks from any thread.
let serialQueue = DispatchQueue(label: "serial_queue")
serialQueue.async {
self.testLog(name: "first")
}
serialQueue.async {
self.testLog(name: "second")
}
serialQueue.async {
self.testLog(name: "third")
}
Upvotes: 3