How to make thread safe code block in swift
Clash Royale CLAN TAG#URR8PPP
How to make thread safe code block in swift
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.
create a serial queue and add testLog() to the queue.
– vivekDas
Aug 10 at 7:32
2 Answers
2
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.
static let
static let
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)
This will execute the calls serially.
Keep a reference to serialQueue
and you can submit blocks from any thread.
serialQueue
let serialQueue = DispatchQueue(label: "serial_queue")
serialQueue.async
self.testLog(name: "first")
serialQueue.async
self.testLog(name: "second")
serialQueue.async
self.testLog(name: "third")
Can do like-> serialQueue.async self.testLog(name: "first") self.testLog(name: "second") self.testLog(name: "third") in one async block only.
– vivekDas
Aug 10 at 7:32
that is true, but i was trying to demo that each
async
call can be made from different threads in different places in the code– Aris
Aug 10 at 7:36
async
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
i have tried multiple things, but not mentioned in example code in my question, so requesting you please test you answer before posting
– shesh nath
Aug 10 at 7:11