Dispatch

RSS for tag

Execute code concurrently on multicore hardware by submitting work to dispatch queues managed by the system using Dispatch.

Posts under Dispatch tag

25 Posts

Post

Replies

Boosts

Views

Activity

Some fundamental doubts about DisptachQueue and GCD
I understand that GCD and it's underlying implementations have evolved over time. And many things have not been shared explicitly in Apple documentation. The most concepts of DispatchQueue (serial and concurrent queues), DispatchQoS, target queue and system provided queues: main and globals etc. I have some doubts & questions to clarify: [Main Dispatch Queue] [Link] Because the main queue doesn't behave entirely like a regular serial queue, it may have unwanted side-effects when used in processes that are not UI apps (daemons). For such processes, the main queue should be avoided. What does it mean? Can you elaborate? [Global Concurrent Dispatch Queues] Are they global to a process or across processes on a device. I believe it is the first case but just wanted to be sure. [Global Concurrent Dispatch Queues] Does system create 4 (for each QoS) * 2 (over-commiting and non-overcommiting queues) = 8 queues in all. When does which type of queue comes into play? [Custom Queue][Target Queue concept] [swift-corelibs-libdispatch/man/dispatch_queue_create.3] QUOTE The default target queue of all dispatch objects created by the application is the default priority global concurrent queue. UNQUOTE Is this stil true? We could not find a mention of this in any latest official apple documentation (though some old forum threads (one more) and github code documentation indicate the same). The official documentation only says: [dispatch_set_target_queue] QUOTE If you want the system to provide a queue that is appropriate for the current object UNQUOTE [dispatch_queue_create_with_target] QUOTE Specify DISPATCH_TARGET_QUEUE_DEFAULT to set the target queue to the default type for the current dispatch queue.UNQUOTE [Dispatch>DispatchQueue>init] QUOTE Specify DISPATCH_TARGET_QUEUE_DEFAULT if you want the system to provide a queue that is appropriate for the current object. UNQUOTE What is the difference between passing target queue as 'nil' vs 'DISPATCH_TARGET_QUEUE_DEFAULT' to DispatchQueue init? [Custom Queue][Target Queue concept] [dispatch_set_target_queue] QUOTE The system doesn't allocate threads to the dispatch queue if it has a target queue, unless that target queue is a global concurrent queue. UNQUOTE The system does allocate threads to the custom dispatch queues that have global concurrent queue as the default target. What does that mean? Why does targetting to global concurrent queues mean in that case? [System / GCD Thread Pool] that excutes work items from DispatchQueue: Is this thread pool per queue? or across queues per process? or across processes per device?
14
0
1.2k
Feb ’25
Unexpected behavior of dispatch_main on macOS
Hi! We are seeing a bit surprising behavior of dispatch_main on macOS where it seems to spawn a different thread instead of preserving the one it gets called from. Managed to reproduce it in a completely empty command-line tool project in Xcode int main(int argc, const char * argv[]) { @autoreleasepool { dispatch_main(); return 0; } } I put a breakpoint on the line with dispatch_main and see that I am on Thread 1 and inside main function. That makes sense. I resume execution and pause again. Looking at Thread output in Xcode, I can only see Thread 2. Thread 1 is gone and the executable keeps on running. So dispatch_main did what was expected (prevented the process from termination) but throws out the thread it was called from and creates a new one? Is that behavior expected or am I missing something? Just a brain teaser at this point. But we could not make sense out of it. :)
4
1
577
Jan ’25
SwiftUI crashes EXC_BREAKPOINT at _dispatch_semaphore_dispose
Based on crash reports for our app in production, we're seeing these SwiftUI crashes but couldn't figure out why it is there. These crashes are pretty frequent (>20 crashed per day). Would really appreciate it if anyone has any insight on why this happens. Based on the stacktrace, i can't really find anything that links back to our app (replaced with MyApp in the stacktrace). Thank you in advance! Crashed: com.apple.main-thread 0 libdispatch.dylib 0x39dcc _dispatch_semaphore_dispose.cold.1 + 40 1 libdispatch.dylib 0x4c1c _dispatch_semaphore_signal_slow + 82 2 libdispatch.dylib 0x2d30 _dispatch_dispose + 208 3 SwiftUICore 0x77f788 destroy for StoredLocationBase.Data + 64 4 libswiftCore.dylib 0x3b56fc swift_arrayDestroy + 196 5 libswiftCore.dylib 0x13a60 UnsafeMutablePointer.deinitialize(count:) + 40 6 SwiftUICore 0x95f374 AtomicBuffer.deinit + 124 7 SwiftUICore 0x95f39c AtomicBuffer.__deallocating_deinit + 16 8 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 9 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 10 SwiftUICore 0x77e53c StoredLocation.deinit + 32 11 SwiftUICore 0x77e564 StoredLocation.__deallocating_deinit + 16 12 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 13 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 14 MyApp 0x1673338 objectdestroyTm + 6922196 15 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 16 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 17 SwiftUICore 0x650290 _AppearanceActionModifier.MergedBox.__deallocating_deinit + 32 18 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 19 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 20 SwiftUICore 0x651b44 closure #1 in _AppearanceActionModifier.MergedBox.update()partial apply + 28 21 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 22 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 23 libswiftCore.dylib 0x3b56fc swift_arrayDestroy + 196 24 libswiftCore.dylib 0xa2a54 _ContiguousArrayStorage.__deallocating_deinit + 96 25 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 26 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 27 SwiftUICore 0x4a6c4c type metadata accessor for _ContiguousArrayStorage<CVarArg> + 120 28 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 29 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 30 SwiftUICore 0x4a5d88 static Update.dispatchActions() + 1332 31 SwiftUICore 0xa0db28 closure #2 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 132 32 SwiftUICore 0xa0d928 closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 708 33 SwiftUICore 0xa0b0d4 ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 556 34 SwiftUI 0x8f1634 UIHostingViewBase.renderForPreferences(updateDisplayList:) + 168 35 SwiftUI 0x8f495c closure #1 in UIHostingViewBase.requestImmediateUpdate() + 72 36 SwiftUI 0xcc700 thunk for @escaping @callee_guaranteed () -> () + 36 37 libdispatch.dylib 0x2370 _dispatch_call_block_and_release + 32 38 libdispatch.dylib 0x40d0 _dispatch_client_callout + 20 39 libdispatch.dylib 0x129e0 _dispatch_main_queue_drain + 980 40 libdispatch.dylib 0x125fc _dispatch_main_queue_callback_4CF + 44 41 CoreFoundation 0x56204 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 42 CoreFoundation 0x53440 __CFRunLoopRun + 1996 43 CoreFoundation 0x52830 CFRunLoopRunSpecific + 588 44 GraphicsServices 0x11c4 GSEventRunModal + 164 45 UIKitCore 0x3d2eb0 -[UIApplication _run] + 816 46 UIKitCore 0x4815b4 UIApplicationMain + 340 47 SwiftUI 0x101f98 closure #1 in KitRendererCommon(_:) + 168 48 SwiftUI 0xe2664 runApp<A>(_:) + 100 49 SwiftUI 0xe5490 static App.main() + 180 50 MyApp 0x8a7828 main + 4340250664 (MyApp.swift:4340250664) 51 ??? 0x1ba496ec8 (Missing)
0
0
540
Jan ’25
What DispatchQueues should i use for my app's communication subsystem?
We would be creating N NWListener objects and M NWConnection objects in our process' communication subsystem to create server sockets, accepted client sockets on server and client sockets on clients. Both NWConnection and NWListener rely on DispatchQueue to deliver state changes, incoming connections, send/recv completions etc. What DispatchQueues should I use and why? Global Concurrent Dispatch Queue (and which QoS?) for all NWConnection and NWListener One custom concurrent queue (which QoS?) for all NWConnection and NWListener? (Does that anyways get targetted to one of the global queues?) One custom concurrent queue per NWConnection and NWListener though all targetted to Global Concurrent Dispatch Queue (and which QoS?)? One custom concurrent queue per NWConnection and NWListener though all targetted to single target custom concurrent queue? For every option above, how am I impacted in terms of parallelism, concurrency, throughput &amp; latency and how is overall system impacted (with other processes also running)? Seperate questions (sorry for the digression): Are global concurrent queues specific to a process or shared across all processes on a device? Can I safely use setSpecific on global dispatch queues in our app?
13
0
984
Jan ’25
Help Needed: How to Make iOS Timer More Stable?
I’m currently developing an iOS metronome app using DispatchSourceTimer as the timer. The interval is set very small, around 50 milliseconds, and I’m using CFAbsoluteTimeGetCurrent to calculate the elapsed time to ensure the beat is played within a ±0.003-second margin. The problem is that once the app goes to the background, the timing becomes unstable—it slows down noticeably, then recovers after 1–2 seconds. When coming back to the foreground, it suddenly speeds up, and again, it takes 1–2 seconds to return to normal. It feels like the app is randomly “powering off” and then “overclocking.” It’s super frustrating. I’ve noticed that some metronome apps in the App Store have similar issues, but there’s one called “Professional Metronome” that’s rock solid with no such problems. What kind of magic are they using? Any experts out there who can help? Thanks in advance! P.S. I’ve already enabled background audio permissions. The professional metronome that has no issues: https://link.zhihu.com/?target=https%3A//apps.apple.com/cn/app/pro-metronome-%25E4%25B8%2593%25E4%25B8%259A%25E8%258A%2582%25E6%258B%258D%25E5%2599%25A8/id477960671
2
0
559
Jan ’25