How to get a "parent" thread for NSThread in iOS? - ios

Assuming the "parent" thread is not the main thread. How can I know from the thread what thread has triggered its creation?
Example:
Main thread triggers creation of ThreadA
ThreadA triggers creation of ThreadB
In ThreadB I want to know that ThreadA is it's "parent"
UPD:
I am not creating a thread in my app. I am trying to instrument existing applications.

You can't. There is no such thing as parent thread. A thread is an independent entity, even if a thread can communicate with other threads but there is no hierarchy involved.

Can you just give the "currentThread" as an argument when you "detachNewThreadSelector:toTarget:withObject:" ?

As the previous post states you can't directly access the "parent" thread of another thread because a NSThread is independent.
But you can create a mechanism to access the thread that started the current thread, indirectly, using the -threadDictionary or the -name/setName methods.
Basically you can create a custom thread pool that will handle the threads lifecycle and can be accessed from other threads.
But as an observation, I don't see a use of this mechanism. If you really want to run tasks on background and you want to be able to change the lifecycle of the background tasks (cancel/start/etc) you should use NSOperation and NSOperationQueue, this ones will give you all the feature required for a custom thread pool.

Related

How to make sure that OperationQueue tasks are always getting executed on background(global) thread in swift?

I encountered a problem with non-iOS developer while describing the flow of OperationQueue. We already know that with OperationQueue we can start as many threads as we want to execute the tasks in sync/async way.
But in practical, some of the people want proof for the OperationQueue is getting executed in the background and not with UI(Main) thread.
I just want to demonstrate that when operation queue starts, it already starts its execution in the background.
I already have convinced that when we try to set qos for the operationQueue that we create, it has all the parameters of global queue's qos viz: default userInitiated userInteractive background and utility.
So that is already perfect example in code to prove that all the OperationQueue operations mentioned are run on global thread. Unless we declare the OperationQueue.main
As Shadowrun said, you can add assertions for Thread.isMainThread. Also, if you ever want to add test that you are not on the main queue, you can add a precondition:
dispatchPrecondition(.notOnQueue(.main))
But it should be noted that the whole purpose of creating an operation queue is to get things off the main thread. E.g., the old Concurrency Programming Guide: Operation Queues says [emphasis added]:
Operations are designed to help you improve the level of concurrency in your application. Operations are also a good way to organize and encapsulate your application’s behavior into simple discrete chunks. Instead of running some bit of code on your application’s main thread, you can submit one or more operation objects to a queue and let the corresponding work be performed asynchronously on one or more separate threads.
This is not to say that operation queues cannot contribute to main thread responsiveness problems. You can wait from the main thread for operations added to an operation queue (which is obviously a very bad idea). Or, if you neglect to set a reasonable maxConcurrentOperationCount and have thread explosion, that can introduce all sorts of unexpected behaviors. Or you can entangle the main thread with operation queues through a misuse of semaphores or dispatch groups.
But operations on an operation queue (other than OperationQueue.main) simply do not run on the main thread. Technically, you could get yourself in trouble if you started messing with the target queue of the underlying queue, but I can’t possibly imagine that you are doing that. If you are having main thread problems, your problem undoubtedly rests elsewhere.

Are threads shared between different Dispatch queues?

Can a single thread be used in different dispatch queues?
I'm developing an app where i want to get a value depending on the thread where the code is running. For that i change the name of the thread when the block starts in a custom queue.
For example, if I add a block to mi custom queue, and i change the name of that thread to "SyncThread". Does a block called in a default system queue will be executed in that "SyncThread"?
Can a single thread be used in different dispatch queues?
Yes, and this is common. (The concept of "different dispatch queues" is itself problematic, since queues can, and do, target other queues. Seemingly simple questions like "what is the current queue" are not well defined.)
I'm developing an app where i want to get a value depending on the thread where the code is running. For that i change the name of the thread when the block starts in a custom queue.
What you likely want for this is queue contextual data rather than thread-specific data (usually called thread-local storage). See DispatchQueue.setSpecific(key:value:).
You use the terms thread and queue interchangeably but they aren't interchangeable; they're two distinct things. Apple doesn't want developers threading anymore, they want developers queueing their tasks. The queueing is handled by GCD which does all the threading behind the scenes. This means that two queues can certainly run on the same thread. And while all tasks within a queue run on distinct threads, not every task is guaranteed to run on the same thread, so keep that in mind. Therefore, I would take the advice given here to focus instead on queue context, not thread context.

How to ensure that some code runs on same background thread with runloop

I am using realm in an iOS app.
I am calling realm methods in a background thread. Realm objects can be used only in the thread where it was created.
This means that I have to ensure that all the code related to accessing realm objects happen on the same thread. This question has been answered here - How to ensure to run some code on same background thread?
The background thread has no runloop and hence realm objects do not get refreshed automatically.
Can any one point out how to create a background thread with a runloop so that the code blocks can be executed on the same background thread with runloop?
Not knowing more about your use case (or Realm for that matter!) a suggestion - do you need to use a background thread at all?
Seems that some suggest the Main UI Thread is fine most of the time and may simplify your life.
Is it acceptable to load Realm objects in the main ui thread?

If the secondary thread is created by NSThread could change detach state to joinable state?

I know the default state of secondary thread created by NSThread is detached, I want to know if I could change the state to joinable use some api of NSThread rather than pthread?
As per Apple's thread management guide:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/10000057i-CH15-SW2
If you do want to create joinable threads, the only way to do so is using POSIX threads.
POSIX creates threads as joinable by default. To mark a thread as detached or joinable, modify the thread attributes using the pthread_attr_setdetachstate function prior to creating the thread. After the thread begins, you can change a joinable thread to a detached thread by calling the pthread_detach function. For more information about these POSIX thread functions, see the pthread man page. For information on how to join with a thread, see the pthread_join man page.

NSOperation using GCD, ensure all on the same thread

I have a 'concurrent' NSOperation, and during it's work it uses some controller classes that internally use GCD. When these controller classes return with their completion block, the completion block is on another thread.
I know I could store the current thread in the operation start method and run performSelectorOnThread:, but ideally I would like to wrap the completion in a GCD block and dispatch onto the same thread as the operation started on. Is this even possible with GCD, as I can only specify a queue to dispatch to.
What's the best way to bring this work back onto the same thread that the operation started on? Apart from what I already suggested... unless this is the best way.
When the operation is completed the UI update or any other related things has to be done on main thread. The following link might be useful to you about CGD.
http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial
I don't think this is really possible/advisable. Since iOS 4 onwards, NSOperation is using GCD , and as GCD is managing my threads - I don't think I should be keeping references to them.
I did find some util methods for executing blocks of code on a particular thread. See Practical Blocks by Mike Ash or this article doing similar thing.
As my goal was to keep my core data calls on the same thread, instead I opted to upgrade my code to use parent/child managed object contexts with NSPrivateQueueConcurrencyType, and then used performBlock: on the managed object context to ensure all my call backs on the separate threads got executed correctly by core data.

Resources