Processes & Concurrency

RSS for tag

Discover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.

Concurrency Documentation

Post

Replies

Boosts

Views

Activity

Tasks shown "alive" in Instruments display even after they should have finished.
In my TestApp I run the following code, to calculate every pixel of a bitmap concurrently: private func generate() async {     for x in 0 ..< bitmap.width{         for y in 0 ..< bitmap.height{             let result = await Task.detached(priority:.userInitiated){                return iterate(x,y)             }.value             displayResult(result)         }     } } This works and does not give any warnings or runtime issues. After watching the WWDC talk "Visualize and optimize Swift concurrency" I used instruments to visualize the Tasks: The number of active tasks continuously raises until 2740 and stays constant at this value even after all 64000 pixels have been calculated and displayed. What am I doing wrong?
2
0
1.3k
Jun ’22
POSIX read/write thread safety: is sharing socket descriptors between threads on macOS correct?
Hi, Despite the following code works great on Windows and Linux (well, there is an OS layer stripped from the code), it hangs on macOS (pseudocode first): create non-blocking socketpair(AF_UNIX, SOCK_STREAM, ...); + a couple of fcntl(fd, ..., flags | O_NONBLOCK) spawn 128 pairs of threads (might be as little as 32, but will need several iterations to reproduce). Of course, there is the errno check to ensure there are no errors but EWOULDBLOCK / EAGAIN readers read a byte 10000 times: for (...) { while (read(fd[1]...) < 1) select(...); r++;} writers write a byte 10000 times: for (...) { while (write(fd[0]...) < 1) select(...); w++;} Join writers; Join readers; On Linux/Windows with the iterations number really cranked up, I'm getting a socket buffer overflow, so ::write returns EWOULDBLOCK, then I'm waiting on a socket until it's ready, continue, and after joining both sets of threads I see that bytes-read is equal to bytes-written, everything fine. However, on macOS I quickly end up in a strange lock when writers are waiting on ::select(...., &write_fds, ...) and readers on the corresponding ::select(..., &read_fds, ...); I have really no idea how that could happen except that the read/write is not thread-safe. However, it looks like POSIX docs and manpages state that it is (at least, reentrant). Could anyone point me in the right direction? Detailed code below: std::atomic<int> bytes_written(0); std::atomic<int> bytes_read(0); static constexpr int k_packets = 10000; static constexpr int k_threads = 32; std::vector<std::thread> writers; std::vector<std::thread> readers; writers.reserve(k_threads); readers.reserve(k_threads); for (int i = 0; i < k_threads; ++i) { writers.emplace_back([fd_write = fd[1], &bytes_written]() { char data = 'x'; for (int i = 0; i < k_packets; ++i) { while (::write(fd_write, &data, 1) < 1) { fd_set writefds; FD_ZERO(&writefds); FD_SET(fd_write, &writefds); assert(errno == EAGAIN || errno == EWOULDBLOCK); int retval = ::select(fd_write + 1, nullptr, &writefds, nullptr, nullptr); if (retval < 1) assert(errno == EAGAIN || errno == EWOULDBLOCK); } ++bytes_written; } }); readers.emplace_back([fd_read = fd[0], &bytes_read]() { char data; for (int i = 0; i < k_packets; ++i) { while (::read(fd_read, &data, 1) < 1) { fd_set readfds; FD_ZERO(&readfds); FD_SET(fd_read, &readfds); assert(errno == EAGAIN || errno == EWOULDBLOCK); int retval = ::select(fd_read + 1, &readfds, nullptr, nullptr, nullptr); if (retval < 1) assert(errno == EAGAIN || errno == EWOULDBLOCK); } ++bytes_read; } }); } for (auto& t : writers) t.join(); for (auto& t : readers) t.join(); assert(bytes_written == bytes_read);
0
0
460
Dec ’23
Concurrency Resources
Swift Concurrency Resources: DevForums tags: Concurrency The Swift Programming Language Concurrency > Concurrency documentation WWDC 2022 Session 110351 Eliminate data races using Swift Concurrency — This ‘sailing on the sea of concurrency’ talk is a great introduction to the fundamentals. WWDC 2021 Session 10134 Explore structured concurrency in Swift — The table that starts rolling out at around 25:45 is really helpful. Dispatch Resources: DevForums tags: Dispatch Dispatch documentation — Note that the Swift API and C API, while generally aligned, are different in many details. Make sure you select the right language at the top of the page. Dispatch man pages — While the standard Dispatch documentation is good, you can still find some great tidbits in the man pages. See Reading UNIX Manual Pages. Start by reading dispatch in section 3. WWDC 2015 Session 718 Building Responsive and Efficient Apps with GCD [1] WWDC 2017 Session 706 Modernizing Grand Central Dispatch Usage [1] Avoid Dispatch Global Concurrent Queues DevForums post Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] These videos may or may not be available from Apple. If not, the URL should help you locate other sources of this info.
0
0
669
Nov ’23
libxpc library crash on top of callstack after iOS 16 version
Hi team, We found that the app reported a lot of crash stacks, and the top of the stack had the libxpc library feature, but we could not find the reason. These issues have only emerged since iOS 16 and are growing, can you provide some clues or provide some solutions? Thanks! Crash backtrace can be seen as follows. _ OS Version: 16.6.1 (20G81) Report Version: 104 SDK start time: 2023-09-20 18:42:40 RDM SDK Version: 2.7.27.1 RDM user id : 119902290602 RDM DeviceId: 0DB20076-F323-468F-9EEC-080B77A00E05 RDM APP KEY: 7c35edbf90 Last Exception : 0 libxpc.dylib 0x000000020a019e98 __xpc_dictionary_insert + 96 1 libxpc.dylib 0x000000020a019e84 __xpc_dictionary_insert + 76 2 libxpc.dylib 0x000000020a01b944 __xpc_dictionary_deserialize_apply + 68 3 libxpc.dylib 0x000000020a01b8cc __xpc_dictionary_apply_wire_f + 136 4 libxpc.dylib 0x000000020a018da4 __xpc_dictionary_deserialize + 108 5 libxpc.dylib 0x000000020a00cdf4 __xpc_array_deserialize + 204 6 libxpc.dylib 0x000000020a01b9ec __xpc_dictionary_unpack_value + 120 7 libxpc.dylib 0x000000020a01bbf0 __xpc_dictionary_unpack_value_and_vend + 28 8 libxpc.dylib 0x000000020a01a4c4 __xpc_dictionary_look_up + 156 9 libxpc.dylib 0x000000020a01b094 _xpc_dictionary_get_array + 20 10 libdns_services.dylib 0x000000020a0b9a28 ____dnssd_client_connection_block_invoke_2 + 320 11 libxpc.dylib 0x000000020a015af0 __xpc_connection_call_event_handler + 152 12 libxpc.dylib 0x000000020a015f20 __xpc_connection_mach_event + 992 13 libdispatch.dylib 0x00000001b1657f6c __dispatch_client_callout4 + 20 14 libdispatch.dylib 0x00000001b16746ec __dispatch_mach_msg_invoke + 468 15 libdispatch.dylib 0x00000001b165f40c __dispatch_lane_serial_drain + 372 16 libdispatch.dylib 0x00000001b1675438 __dispatch_mach_invoke + 448 17 libdispatch.dylib 0x00000001b165f40c __dispatch_lane_serial_drain + 372 18 libdispatch.dylib 0x00000001b16600a4 __dispatch_lane_invoke + 384 19 libdispatch.dylib 0x00000001b166acdc __dispatch_workloop_worker_thread + 648 20 libsystem_pthread.dylib 0x0000000209fc1ddc __pthread_wqthread + 288 Exception Type: SIGSEGV SEGV_ACCERR Exception Codes: fault addr: 0x0000000000000036 Crashed Thread: 7 _
14
0
1.8k
Sep ’23
Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context
Can't understand why this compiles extension HomeReducer { @MainActor @Observable final class State: BaseState { var isPresentingSubscription = false } } class BaseState {} but this gives an error Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context extension HomeReducer { @MainActor @Observable final class State { var isPresentingSubscription = false } } extension DependencyValues { var homeView: @Sendable () -> HomeView { HomeKey().value } private struct HomeKey: DependencyKey { typealias Value = @Sendable () -> HomeView let liveValue: Value = { HomeView(store: Store(initialState: HomeReducer.State(), reducer: HomeReducer())) } let testValue: Value = { fatalError("testValue not implemented") } var previewValue: Value = { fatalError("previewValue not implemented") } } }
5
0
5.0k
Oct ’23
NSXPC
I have another NSXPC problem, and the problem goes like this NSXPC server implements an interface -(void) callbackWithInfo:(NSDictionary*)log reply:(void (^)(bool))action; The NSXPC client implements a method that will call the interface in a loop and perform a timeout operation. If the server returns to the interface and does not call the action after 1s, the client will perform subsequent operations. The callbackWithInfo interface is then called again, and the cycle continues. client code: The general structure is as follows while(true){ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [serverProxy callbackWithInfo:InfoDic reply:^(bool action) { if(flag != NO){ flag = action; } }]; dispatch_semaphore_signal(semaphore); }); if(dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, self.waitTime *NSEC_PER_MSEC)) != 0){ NSLog(@"flag: %d", flag); } sleep(0.1); } If the action callback is not invoked on the server, the number of FDS on the client increases. As a result, the process cannot open the file, or too much program context information is generated. As a result, the NSXPC interface fails to be invoked. Now I can not operate on the server side, how can the client side implement the code to ensure that the action will not be punished, and the fd will not increase.
2
0
500
Oct ’23
fatal error: Index out of range...
class CalculatorViewModel : NSObject, ObservableObject, Identifiable { var id = UUID() @Published var output = "Disconnected" @Published var connected = false @Published var databasePath = String() enum itemType : Int{ case angle = 1 case degree = 2 case grip1 = 3 case grip2 = 4 } struct test_Array: Identifiable { var id = UUID() var time: String var swingNum : Int var dataSeqInSwing: Int var timeStampInSeq: Double var itemType: Int var value: Double } @Published var testDBdata = [test_Array] () ..... private var centralManager: CBCentralManager? func connectCalculator() { output = "Connecting..." centralQueue = DispatchQueue(label: "test.discovery") centralManager = CBCentralManager(delegate: self, queue: centralQueue) } .... func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { ..... if characteristic.uuid == outputCharUUID, var data = characteristic.value { ..... DispatchQueue.main.async() { for index in tupleSets { strItemSets = index.components(separatedBy: ",") ....... var itemN = 1 for indexStr in strItemSets { self.golfDBdata[numDB].dataSeqInSwing = countItem. <= Error self.golfDBdata[numDB].itemType = itemN self.golfDBdata[numDB].value = Double(strItemSets[itemN]) ?? 0.0
5
0
709
Oct ’23
[client] No error handler for XPC error: Connection invalid
Hello everyone, With the MacOS update to Venture 13.2, I get the following error message when closing a MacOS app in xCode: [client] No error handler for XPC error: Connection invalid Today I set up a brand new MacOS system which has nothing more installed as except for MacOS Venture 13.2 and xCode 14.2 (14C18). The error already occurs when I start an app that only contains template code. I also started the app without xCode and then closed it through the menu. Then I do not receive an error message. With the Ventura version 13.1 on an AirBook with M1, the problem did not exist. On my Intel iMac, the error causes the iMac to no longer start normally. Thank you very much for your support.
4
3
5.3k
Feb ’23
Faulty, hard-to-understand XPC behavior with remote methods that have a reply-block
Assume this over-simplified @protocol I'm using for my XPC-service: @protocol MyMinimalProtocol <NSObject> - (void)getStatusWithReply:(void (^ _Nullable)(NSDictionary * _Nonnull))reply; @end The Client side would then NSXPCConnection *connection = [[NSXPCConnection alloc] initWithMachServiceName:myServiceLabel options:NSXPCConnectionPrivileged]; connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyMinimalProtocol)]; connection.interruptionHandler = ^{ NSLog(@"XPC: connection - interrupted"); }; connection.invalidationHandler = ^{ NSLog(@"XPC: connection - invalidated"); }; [connection resume]; [connection.remoteObjectProxy getStatusWithReply:^(NSDictionary * response) { NSLog(@"XPC service status received - %@", response); }]; So far - so good. My XPC service receives the asynchronous call, schedules it's "status gathering operation" on internal background queue, and returns. Later - when information is available, my XPC service executes the reply-block then, on the remote calling side - I see the log line with the status, as expected. BUT!!! If I add another different code-block argument to the method e.g. @protocol MyMinimalProtocol <NSObject> - (void)getStatusWithReply:(void (^ _Nullable)(NSDictionary * _Nonnull))reply andFailureBlock:(void (^ _Nullable)(NSError * _Nonnull))failureBlock; @end Then all hell breaks loose. Both XPC service and the client crash with hilarious crash reasons I can't decipher. Here's "Client side" caller crash (excerpt - forgive the methods are NOT the simplified ones above) XPC Client(Caller) side crash - excerpt while on the "XPC Service" side, crashes like these: XPC service side crash excerpt I wonder if there's something inherently wrong with having two code-block arguments for an XPC remote method? Another issue. The client XPC calls are asynchronous. They return immediately. The XPC service implementing the remote-call also returns immediately - and it executes the "reply block" far (a minute!) later, on another queue. However, if the XPC service attempts to execute the code-block MORE THAN ONCE, then the client-side code-block is only called ONCE. rest of the executions look benign in the XPC-service side - but never happen on the calling (client) side. Any idea why? can this be overcome? Any thoughts/ideas/references to documentation will be greatly appreciated. I couldn't find any good source on this. Thanks.
4
0
1k
Sep ’23
app crash at com.apple.root.default-qos Dispatch queue
I implemented a multithreaded app, but there was a thread-related crash in the app, I don't understand why this happened, the corresponding stack trace is as follows. Thread 15 Crashed:: Dispatch queue: com.apple.root.default-qos 0 libsystem_kernel.dylib 0x1a849ad98 __pthread_kill + 8 1 libsystem_pthread.dylib 0x1a84cfee0 pthread_kill + 288 2 libsystem_c.dylib 0x1a840a340 abort + 168 3 libc++abi.dylib 0x1a848ab08 abort_message + 132 4 libc++abi.dylib 0x1a847a950 demangling_terminate_handler() + 336 5 libobjc.A.dylib 0x1a8370320 _objc_terminate() + 144 6 libc++abi.dylib 0x1a8489ea4 std::__terminate(void (*)()) + 20 7 libc++abi.dylib 0x1a8489e40 std::terminate() + 64 8 libdispatch.dylib 0x1a830c1c8 _dispatch_client_callout + 40 9 libdispatch.dylib 0x1a831da04 _dispatch_root_queue_drain + 680 10 libdispatch.dylib 0x1a831e104 _dispatch_worker_thread2 + 164 11 libsystem_pthread.dylib 0x1a84cc324 _pthread_wqthread + 228 12 libsystem_pthread.dylib 0x1a84cb080 start_wqthread + 8
3
0
1.1k
Sep ’23
libxpc library crash on top of callstack after iOS 16 version
Hi team, We found that the app reported a lot of crash stacks, and the top of the stack had the libxpc library feature, but we could not find the reason. These issues have only emerged since iOS 16 and are growing, can you provide some clues or provide some solutions? Thanks Crash backtrace can be seen as follows. _ OS Version: 16.6.1 (20G81) Report Version: 104 SDK start time: 2023-09-20 18:42:40 RDM SDK Version: 2.7.27.1 RDM user id : 119902290602 RDM DeviceId: 0DB20076-F323-468F-9EEC-080B77A00E05 RDM APP KEY: 7c35edbf90 Last Exception : 0 libxpc.dylib 0x000000020a019e98 __xpc_dictionary_insert + 96 1 libxpc.dylib 0x000000020a019e84 __xpc_dictionary_insert + 76 2 libxpc.dylib 0x000000020a01b944 __xpc_dictionary_deserialize_apply + 68 3 libxpc.dylib 0x000000020a01b8cc __xpc_dictionary_apply_wire_f + 136 4 libxpc.dylib 0x000000020a018da4 __xpc_dictionary_deserialize + 108 5 libxpc.dylib 0x000000020a00cdf4 __xpc_array_deserialize + 204 6 libxpc.dylib 0x000000020a01b9ec __xpc_dictionary_unpack_value + 120 7 libxpc.dylib 0x000000020a01bbf0 __xpc_dictionary_unpack_value_and_vend + 28 8 libxpc.dylib 0x000000020a01a4c4 __xpc_dictionary_look_up + 156 9 libxpc.dylib 0x000000020a01b094 _xpc_dictionary_get_array + 20 10 libdns_services.dylib 0x000000020a0b9a28 ____dnssd_client_connection_block_invoke_2 + 320 11 libxpc.dylib 0x000000020a015af0 __xpc_connection_call_event_handler + 152 12 libxpc.dylib 0x000000020a015f20 __xpc_connection_mach_event + 992 13 libdispatch.dylib 0x00000001b1657f6c __dispatch_client_callout4 + 20 14 libdispatch.dylib 0x00000001b16746ec __dispatch_mach_msg_invoke + 468 15 libdispatch.dylib 0x00000001b165f40c __dispatch_lane_serial_drain + 372 16 libdispatch.dylib 0x00000001b1675438 __dispatch_mach_invoke + 448 17 libdispatch.dylib 0x00000001b165f40c __dispatch_lane_serial_drain + 372 18 libdispatch.dylib 0x00000001b16600a4 __dispatch_lane_invoke + 384 19 libdispatch.dylib 0x00000001b166acdc __dispatch_workloop_worker_thread + 648 20 libsystem_pthread.dylib 0x0000000209fc1ddc __pthread_wqthread + 288 Exception Type: SIGSEGV SEGV_ACCERR Exception Codes: fault addr: 0x0000000000000036 Crashed Thread: 7 _
1
1
526
Sep ’23
The nsxpc interface is not invoked
Hello, I encountered such a problem, the scenario is like this: I have a launchctl startup daemon called xpcserver.app, which uses NSXPC to start an xpc Server. There is a Client program that links to the nsxpc service of this xpcserver.app, and when I establish the connection, I call an interface implemented by xpcserver named setName:(nsstring*)name. I was sure that my xpcserver implemented the corresponding interface, but when the client called the interface to pass the value, it triggered the error "unrecognized selector sent to instance". When I restarted the client, the call to the interface successfully implemented the function. May I ask why? Using the NSXPC started service, hope to solve, thank you
3
0
555
Sep ’23
WWDC 2015 video on GCD missing (again)
In a thread titled “Avoid Dispatch Global Concurrent Queues” [1], Quinn links to a video from WWDC 2015 Session 718, “Building Responsive and Efficient Apps with GCD”. However, this video is not available from the Apple Developer Videos site; only a half dozen or so videos from 2015 are available. This same issue of the missing video came up about five years ago, when Quinn stated that the video had been mistakenly removed but had been restored. Now it’s gone again. :sad_face: Could this video be restored again, or at least its transcript? While I understand that Apple is focused on Swift concurrency, I need to maintain some Objective-C code that uses GCD, and in tracking down some performance issues, I would like to better understand the tradeoffs in the existing code and make improvements where I can. I don’t have the resources to reimplement the code in Swift right now. (More generally, why can't Apple just leave all these videos online indefinitely, for historical purposes at least? Couldn't the ones deemed “old and misleading” just be tagged with a banner like the legacy documentation has?) [1] I like to think of these valuable threads as “Quinn Technical Notes”; I have a page in my Notes app that holds links to the ones I’ve found.
5
1
811
Aug ’23
I think there's a logic error in Apple SwiftUI tutorial Scrumdinger.
Hi. In Apple's SwiftUI Tutorial Scrumdinger, there's a logic that read and save a file in asynchronous function to keep the App's UI responsive. The tutorial says, Reading from the file system can be slow. To keep the interface responsive, you’ll write an asynchronous function to load data from the file system. Making the function asynchronous lets the system efficiently prioritize updating the user interface instead of sitting idle and waiting while the file system reads data. And here's code. @MainActor class ScrumStore: ObservableObject { @Published var scrums: [DailyScrum] = [] func load() async throws { let task = Task<[DailyScrum], Error> { let fileURL = try Self.fileURL() guard let data = try? Data(contentsOf: fileURL) else { return [] } let dailyScrums = try JSONDecoder().decode([DailyScrum].self, from: data) return dailyScrums } let scrums = try await task.value } func save(scrums: [DailyScrum]) async throws { let task = Task { let data = try JSONEncoder().encode(scrums) let outfile = try Self.fileURL() try data.write(to: outfile) } _ = try await task.value } } But the problem i think here is that the ScrumStore is Mainactor isolated annotated, the 'load' and 'save' method execute their Tasks in the main thread, so I think there's not much benefit we can get comparing using a synchronous method. The proper way I think here is that use 'Task.detached' initializer instead of 'Task' initializer, so that the Task doesn't isolated in MainActor context. If there's anything I understand wrong or miss, please let me know. Apple's Scrumdinger Tutorial Link
1
0
511
Aug ’23
C compiler lies about c11 support
The C compiler accepts the option '-std=c11' and responds by defining the define token '__STDC_VERSION__' = 201112 which thereby claims C11 support. Additionally, it DOES NOT define '__STDC_NO_THREADS__' and therefore the include headers &amp;lt;threads.h&amp;gt; and &amp;lt;stdatomic.h&amp;gt; should exist but they dont. The compiler is promising C11 threads, condition variables, ... support but does NOT provide it. This is NOT a link time problem, it is a compile time issue.
6
0
4.3k
Aug ’15