How can I kill a thread created by performSelectorInBackground:withObject: from the main thread? I need to force termination of freezing threads.
You cannot kill background threads from the main thread, the method that is executing in a background thread has to return for the thread to end.
Your actual problem seems to be that your background thread is freezing, you should solve that instead of trying to work around it.
I'm not sure if this may help but here goes:
Assuming you're calling that performSelector call from class A. And assuming that class A is about to be released from memory in class B (which is where if the selector hasn't been performed yet, you might be getting a crash - Hence you're posting this question on SO):
Wherever you're releasing A from B, do this:
[NSObject cancelPreviousPerformRequestsWithTarget:A];
Apple documentation says
The recommended way to exit a thread is to let it exit its entry point
routine normally. Although Cocoa, POSIX, and Multiprocessing Services
offer routines for killing threads directly, the use of such routines
is strongly discouraged. Killing a thread prevents that thread from
cleaning up after itself. Memory allocated by the thread could
potentially be leaked and any other resources currently in use by the
thread might not be cleaned up properly, creating potential problems
later.
Related
Let's say we have a job A and a job B (not kotlin's Job, just some kind of work).
I am told that coroutines can suspend and thus the underlying thread used by A will not be blocked and can be used for B, while A suspends.
Let's say, that A performs some kind of downloading data from server. How does A perform such work, while being suspended (if it gets suspended)? How does it know that it is time to resume and hold the thread again? How the thread deal with the coroutines states and decides, which one to run?
I guess it uses good old wait/notify mechanism under the hood, however it is unclear for me, how the example download can happen while the thread is used for another work already?
How does the coroutine perform work, while being suspended (if it gets suspended)?
After some research I found out, that when the coroutine suspends it actually gets dispatched to another thread (as was mentioned by bylazy), in which it continues execution.
How does it know that it is time to resume and hold the thread again?
Taking the example from the question, the download will be dispatched to a separate thread of the implicit threadpool (which was mentioned by Tenfour04) and will use continuation object to resume on former thread.
At the same time, the former thread remains available for another work. Whereas Java's Thread has differences that explain why coroutines' performance is higher:
Thread is a different mechanism, which is linked to the native thread of OS. This is the reason why creating hundreds/thousands of threads is impossible - thread consumes a lot of OS' memory. Coroutine is a user-level abstraction of some worker which does not use excessive amount of memory, since it is not linked to native resources and use resources of JVM heap.
Thread gets blocked instead of suspending and dispatching the job to another thread.
Thread cannot be used until its work completes.
Thread is asynchrounous whereas coroutines are sequentional. According to the previous point, a thread performs some kind of work asyncrhonously and cannot be used. On the other hand a coroutine, being a user-friendly abstraction, is executed on the thread and after it gets suspended, the next one gets executed on the same thread. (This point answers to "How the thread deal with the coroutines states and decides, which one to run?")
So the coroutines make the better and more efficient use of threads, taking care of dispatching, reusing resources, managing thread pool and etc.
The sources I used:
Coroutines vs Threads (Educba)
Difference between a thread and a coroutine in Kotlin
I'm creating a new thread using detachNewThreadSelector ref with toTarget self.
The purpose of the thread is to poll movements and load images as appropriate - it loops and only quits when an atomic bool is set to true in the main thread - which is set in the objects dealloc.
The problem is caused by this (from the detachNewThreadSelector reference):
The objects aTarget and anArgument are retained during the execution of the detached thread, then released
Which means my object will always have a (minimum) retain count of one - because the thread continuously polls. dealloc is therefore never called.
So my question is: how can I dealloc my object taking into account the existence of the polling thread?
The only idea I have right now is to create a destroyThread function of the object, which sets the end thread bool, which would be called from everywhere I'd expect the object to be destroyed. This seems error-prone, are there better solutions?
Thanks in advance.
Update
I had an idea for another solution - in the thread I detect if the retain count is one - if it's one then I know the thread is keeping the object alive, so I break the loop and dealloc is called. Is this a robust solution?
First, avoid detachNewThreadSelector:. Anything you are thinking of doing with it is almost certainly done better with a dispatch queue or NSOperationQueue. Even if you need to manually create a thread (which is exceedingly rare in modern ObjC), it is better to create explicit NSThread objects and hold onto them rather than using detachNewThreadSelector: which creates a thread you can't interact directly with anymore.
To the specific question, if you create your own threads, then you'll need to set that bool somewhere other than dealloc. That means that some other part of the program needs to tell you to shut down. You can't just be released and automatically clean yourself up using manual threads this way.
EDIT: Never, ever call retainCount. No solution involving retainCount is a good solution. Putting aside the various practical problems with using retainCount in more general cases, in this case it ties you manual reference counting. You should switch to ARC as quickly as possible, and retainCount is illegal in ARC (it should have been illegal before ARC, but they finally had a really good excuse to force the issue). If you can't implement your solution in ARC, it is unlikely a good solution.
Again, the best solution is to use GCD dispatch queues (or operations, which are generally implemented with dispatch queues). It is incredibly more efficient and effective for almost every problem than manual thread management.
If you must use a manual thread for legacy code and need to maintain this kind of auto-destruct, the solution is a helper object that owns the thread. Your object owns the helper object, which has a retain loop with the thread. When your object is deallocated, then it tells the thread to shut down, which breaks the retain loop, and the helper object goes away. This is a standard way of managing retain loops.
See Apple's Migrating Away From Threads for more.
In my app I use this code to start a NSThread
[NSThread detachNewThreadSelector:#selector(threadStart) toTarget:self withObject:nil];
- (void)threadStart
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
//something to do...
[pool release];
}
my problem is that I want start and stop this thread sometimes, then I have to declare a thread in .h, to have a generic thread...is it possible?
The correct way to stop your thread executing is to ask it nicely to stop executing. Then, in your thread, you listen for such requests and obey them at an appropriate time.
According to Apple's Thread Programming Guide:
Although Cocoa, POSIX, and Multiprocessing Services offer routines for killing threads directly, the use of such routines is strongly discouraged. Killing a thread prevents that thread from cleaning up after itself. Memory allocated by the thread could potentially be leaked and any other resources currently in use by the thread might not be cleaned up properly, creating potential problems later.
If you anticipate the need to terminate a thread in the middle of an operation, you should design your threads from the outset to respond to a cancel or exit message. For long-running operations, this might mean stopping work periodically and checking to see if such a message arrived. If a message does come in asking the thread to exit, the thread would then have the opportunity to perform any needed cleanup and exit gracefully; otherwise, it could simply go back to work and process the next chunk of data.
You could either use [NSThread exit]; in your thread to stop itself i.e. to cancel the current thread,
or you can also use [NSThread cancel] method to signal another thread in your program to cancel..
It's not clear what you're asking. Threads cannot be stopped from another thread (safely). There are several approaches to do work on a background thread and to manage other threads lifetime.
You should describe what you're trying to accomplish. Why do you want to stop the background thread? Is there sometimes no work to be done?
I have created one testing app for running deep counter loop. I run the loop function in background thread using performSelectorInBackground and also NSOperation subclass separately.
I am also using performSelectorOnMainThread to notify main thread within backgroundthread method and [NSNotificationCenter defaultCenter] postNotificationName within NSOperation subclass to notify main thread for updating UI.
Initially both the implementation giving me same result and i am able to update UI without having any problem. The only difference I found is the Thread count between two implementations.
The performSelectorInBackground implementation created one thread and got terminated after loop finished and my app thread count again goes to 1.
The NSOperation subclass implementation created two new threads and keep exists in the application and i can see 3 threads after loop got finished in main() function.
So, my question is why two threads created by NSOperation and why it didn't get terminated just like the first background thread implementation?
I am little bit confuse and unable to decide which implementation is best in-terms of performance and memory management.
It's likely the operation queue is keeping threads alive, waiting for new operations to appear.
You have to remember that the operation queue is designed to work efficiently with many operations, so creating and destroying threads for each operation is going to hurt performance. So what you are seeing is probably just the way the queue is designed to work by keeping a pool of threads alive.
Basically, as long as you are using the operation queue properly and according to the documentation I wouldn't worry about it.
I was trying to set up a multi thread app. One of the threads is working as background to get some data transfer. Right now this thread automatically kill itself after it's job done.
Somehow I need to kill this thread in another thread in order stop its job immediately. Are there any api or method for making this happen?
In short, you can't. Or, more precisely, you should not. Not ever and not under any circumstances.
There is absolutely no way for thread A to know the exact state of thread B when A kills B. If B is holding any locks or in the middle of a system call or calling into a system framework when A kills it, then the resulting state of your application is going to be nondeterministic.
Actually -- it will be somewhat deterministic in that you are pretty much guaranteed that a crash will happen sometime in the near future.
If you need to terminate thread B, you need to do so in a controlled fashion. The most common way is to have a cancel flag or method that can be set/called. thread B then needs to periodically check this flag or check to see if the method has been called, clean up whatever it is doing, and then exit.
That is, you are going to have to modify the logic in thread B to support this.
bbum is correct, you don't want to simply kill a thread. You can more safely kill a process, because it is isolated from the rest of the system. Because a thread shares memory and resources with the rest of the process, killing it would likely lead to all sorts of problems.
So, what are you supposed to do?
The only correct way of handling this is to have a way for your main thread to send a message to the worker thread telling it to quit. The worker thread must check for this message periodically and voluntarily quit.
An easy way to do this is with a flag, a boolean variable accessible by both threads. If you have multiple worker threads, you might need something more sophisticated, though.
Isn't that a bad idea? (If the other thread is in the middle of doing something in a critical section, it could leave stuff in an inconsistent state.) Couldn't you just set some shared flag variable, and have the other thread check it periodically to see if it should stop?
One thing you could do would be pass messages between the front thread and the background thread, potentially using something like this to facilitate message passing.
If you are using pthread then you try with 'pthread_kill' , I had tried long back it did not worked for me, basically if the thread is in some blocking call it won't work.
It is true that killing a thread is not good option, if you are looking for some kind for fix for some issue then you can try with this.
In my personal view it is best to let a thread run its course naturally. It's difficult to make guarantees about the effect of trying to kill a thread.