有没有办法无限期地暂停NSTHread并让它从另一个线程恢复?

时间:2009-08-05 00:17:02

标签: cocoa multithreading xcode

似乎这些是让NSThread进入睡眠状态的唯一方法

* sleepForTimeInterval:

* sleepUntilDate:

我要问的不好吗?

3 个答案:

答案 0 :(得分:17)

你想让你的线程停止直到某个其他线程告诉它再次启动吗?如果是这样,您可以使用NSConditionLock。 NSConditionLock类似于条件变量。它有几个基本方法,lockWhenCondition和unlockWithCondition,以及lock。一个典型的用法是让你的后台线程在条件锁上等待“lockWhenCondition:”,并在前台线程中设置条件,这会导致后台线程被唤醒。条件是一个简单的整数,通常是枚举。

以下是一个例子:

enum {
    kWorkTodo = 1,
    kNoWorkTodo = 0
}

- (id)init {
    if ((self = [super init])) {
        theConditionLock = [[NSCoditionLock alloc] initWithCondition: kNoWorkTodo];
        workItems = [[NSMutableArray alloc] init];
    }
}

- (void)startDoingWork {
    [NSThread detachNewThreadSelector:@selector(doBackgroundWork) toTarget:self withObject:nil];
}

- (void)doBackgroundWork:(id)arg {
    while (YES) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSArray *items = nil;
        [theConditionLock lockWhenCondition:kWorkTodo]; // Wait until there is work to do
        items = [NSArray arrayWithArray:workItems]
        [workItems removeAllObjects];
        [theConditionLock unlockWithCondition:kNoWorkTodo];
        for(id item in items) {
            // Do some work on item.
        }
        [pool drain];
    }
}

- (void)notifyBackgroundThreadAboutNewWork {
    [theConditionLock lock];
    [workItems addObject:/* some unit of work */];
    [theConditionLock unlockWithCondition:kWorkTodo];
}

在这个例子中,当调用startDoingWork时,doBackgroundWork:将在后台线程上启动,但随后停止,因为没有任何工作要做。一旦调用了notifyBackgroundThreadAboutNewWork,那么doBackgroundWork:将启动并处理新工作,然后返回休眠状态等待新工作可用,这将在下次调用notifyBackgroundThreadAboutNewWork时发生。

答案 1 :(得分:2)

如果您确实需要在后台线程上执行任务,但是在执行之前需要完成另一个任务,我建议您查看NSOperation和NSOperationQueue。 NSOperation支持设置非常复杂的依赖关系,NSOperationQueue将按照正确的顺序处理这些操作的调度和执行,然而许多后台线程是合适的。 Apple的documentation就这些非常好,Drew McCormack在MacResearch上有关于这个主题的nice article

答案 2 :(得分:0)

目前尚不清楚自己想做什么。停止线程并在新线程上恢复相同的功能? (那将是毫无意义的 - 旧线程出了什么问题?)停止线程并在另一个现有线程上恢复相同的功能?

无论哪种方式,不,这是不可能的,这甚至都不是一个好主意。正确的解决方案是将您的函数拆分为两个,然后使用部分或全部运行循环,NSTimer,performSelector…方法和NSPort来实现您想要做的任何事情。

如果没有你所想象的所有暗线魔法,你的程序将会更好地工作。