views:

830

answers:

2

Hello

I'm working on a small app written in objective-c with the help of the cocoa framework and I am having a multithreading issue. I would really appreciate it if somebody could help me with some guidance on how terminate a secondary(worker) thread from the main thread?

- (IBAction)startWorking:(id)sender {
     [NSThread detachNewThreadSelector:@selector(threadMain:) toTarget:self withObject:nil];
}

- (void)threadMain
{
  // do a lot of boring, time consuming I/O here..
}

- (IBAction)stop:(id)sender {
  // what now?
}

I've found something on apple's docs but what is missing from this example is the part where the runloop input source changes the exitNow value.

Also, I won't be using many threads in my app so I would prefer a simple solution (with less overhead) rather than a more complex one that is able to manage many threads easily, but with more overhead generated (eg. using locks maybe(?) instead of runloops)

Thanks in advance

+5  A: 

I think the easiest way is to use NSThread's -(void)cancel method. You'll need a reference to the thread you've created, as well. Your example code would look something like this, if you can do the worker thread as a loop:

- (IBAction)startWorking:(id)sender {
     myThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadMain:) object:nil];
     [myThread start];
}

- (void)threadMain
{
    while(1)
    {
        // do IO here
        if([[NSThread currentThread] isCancelled])
            break;
    }
}

- (IBAction)stop:(id)sender {
   [myThread cancel];
   [myThread release];
   myThread = nil; 
}

Of course, this will only cancel the thread between loop iterations. So, if you're doing some long blocking computation, you'll have to find a way to break it up into pieces so you can check isCancelled periodically.

Jesse Rusak
It works great! Thank you!I do have a loop in the thread, so your solution fits like a glove without any additional code breaking :)
andi
You might make the intent of the threadMain's while loop clearer by doing while(![[NSThread currentThread] isCancelled]) instead of while(1) and putting the isCancelled check deep in the loop code.
Barry Wark
@Barry Wark Good point. I guess I was expecting there to be another condition (eg. !done) in that loop.
Jesse Rusak
+1  A: 

Also take a look at the NSOperation and NSOperationQueue classes. It's another set of threading classes that make developing a worker thread model very easy to do.

Marc Charbonneau