如何立即结束一个线程?

如何立即结束一个线程?

本文是作者在实际经验中的心得与体会,开发环境为苹果系统。如果有更好的方式请留言,高手请忽略。转载请注明作者以及出处。


背景

平时开发中经常会有这么个需求:实现在线程中循环执行一些指令,每次循环间隔n秒。那么问题来了,如何能够做到立即结束这个线程?我目前只用GCD,有人可能会说用dispatch_suspend(),这个方法必须和dispatch_resume()成对使用,而且suspend后线程只是暂停而已,并没有释放资源。如果用dispatch_release(),且不说ARC下无法使用这个方法,如果强制释放正在运行的线程资源,程序会直接crash。所以目前在GCD中我也没找到好的方法,要么是我理解不透彻不会用。

第一招

最初的做法是在每次循环时判断一个标志位(bool),如果为false就停止循环,线程随即结束。但是这样带来的一个问题是由于循环每次都要间隔几秒,sleep一下,会导致线程无法立即结束,最长会有那n秒的延迟,这显然不是我所希望看到的。

dispatch_async(dispatch_get_global_queue(0,0), ^(){
    while(running) {
        // do something
        sleep(5);
    }
});

第二招

既然有几秒钟延迟,那就把休眠时间拆分:

dispatch_async(queue, ^(){
    while(running) {
        // do something
        sleep(1); if(!running){break;}
        sleep(1); if(!running){break;}
        sleep(1); if(!running){break;}
        sleep(1); if(!running){break;}
        sleep(1); if(!running){break;}
    }
});

这样做不够优雅,只是把延迟时间缩短而已,还是会有1秒钟的延迟。

第三招

假如还有这样的需求:我不光要能够立即结束线程,还能再次启动它,做到随心所欲的控制。这个是目前能想到的还算满意的方法,把上述启动线程的逻辑做成2个单例,第一次执行时,使用第一个单例;第二次执行时判断如果第一个单例在执行,则结束它,执行第二个单例。这样就不必等第一个线程结束,直接再开一个线程。如果再执行,则最多只会同时出现两个线程而已。

@implement MYClass

+ (id)shareInstance1 {
    ...
}

+ (id)shareInstance2 {
    ...
}

+ (void)func {
    MYClass *obj = [MYClass shareInstance1];
    if (obj.idle) {
        [obj begin];
        MYClass *obj2 = [MYClass shareInstance2];
        if (!obj2.idle) {
            [obj2 end];
        }
    }
    else {
        [obj end];
        MYClass *obj2 = [MYClass shareInstance2];
        [obj2 begin];
    }
}

- (void)begin {
    idle = NO;
    dispatch_async(queue, ^(){
        while(running) {
            ...
        }
        idle = YES;
    });
}

- (void)end {
    running = NO;
}

@end

以上就是我目前能想到的思路,如有更好的方案请告诉我。

你可能感兴趣的:(iOS开发)