从主线程终止一个次要线程(Cocoa)

6

我正在使用Objective-C语言和Cocoa框架编写一个小型应用程序,遇到了多线程问题。我需要一些指导:如何从主线程中终止一个次要(工作)线程?

- (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?
}

我在苹果文档上找到了一些东西,但这个例子缺少了运行循环输入源改变exitNow值的部分。
此外,我的应用程序中不会使用太多线程,因此我更喜欢一个简单的解决方案(开销较小),而不是一个更复杂的解决方案,虽然能够轻松管理多个线程,但会产生更多的开销(例如,可能使用锁代替运行循环)。
提前感谢。
2个回答

12

我认为最简单的方法是使用NSThread的-(void)cancel方法。你需要一个对你创建的线程的引用。如果你可以将工作线程作为一个循环,那么你的示例代码看起来会像这样:

- (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; 
}

当然,这只会取消循环迭代之间的线程。因此,如果你正在进行某个长时间阻塞的计算,你需要找到一种方法将其分解成多个部分,以便可以定期检查isCancelled。


它运行得非常好!谢谢! 我在线程中有一个循环,所以你的解决方案非常适合,没有任何额外的代码破坏 :) - andi
你可以通过使用while(![[NSThread currentThread] isCancelled])而不是while(1),并将isCancelled检查放在循环代码的深处,来使threadMain的while循环的意图更加清晰。 - Barry Wark
@Barry Wark 不错的观点。我想我当时期望在那个循环中还有另一个条件(例如!done)。 - Jesse Rusak

2

同时还需要查看NSOperation和NSOperationQueue类。这是另一组线程类,使得开发工作者线程模型变得非常容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接