一个线程如何确定一个不同的线程是否已崩溃?

时间:2012-10-23 03:55:02

标签: iphone objective-c ios multithreading

我有一个后台线程正在做一堆工作 - 加载应用程序。主线程正在UIProgressView上显示进度。

后台线程正在使用performSelectorInBackground生成(但是,如果不同的方法使这个问题更容易解决,我不会接受这种方法)

[self performSelectorInBackground:@selector(loadAppInBackground) withObject:self];

在某些情况下,一个错误导致后台线程崩溃(应用程序发展时出现不同的错误),导致进度条停止,但用户没有明确指出出现任何问题。

我想要检测到这种情况,并且更优雅地失败,而不是简单地悬挂直到用户放弃等待。

由于加载过程的持续时间可能差异很大,因此简单地超时并不是理想的选择。

前台线程检测后台线程失败的最佳方法是什么?由于前台线程忙于处理UI,它是否需要第二个后台线程来监视第一个?这看起来很难看。

是否有一些线程到线程的通信机制可用于“ping”后台进程?更好的是,检查其他线程状态的低级系统机制?

调试器知道正在运行的所有线程......并且似乎知道它们的状态。我想知道我的应用程序是否有可以执行此操作的电话。

3 个答案:

答案 0 :(得分:1)

如果后台任务以某种常规周期运行(例如,有一个很大的循环来完成大部分工作),它可以经常设置一个标志以表明它仍然存在。

执行此操作的一种方法是在某处将后台线程存储[NSDate timeIntervalSinceReferenceDate],并且在主线程中偶尔(可能在计时器上)将其与当前时间进行比较。如果差异大于某个合理限制,您可以猜测后台线程已经死亡。

另一种方法是让后台线程简单地设置一个布尔值,让主线程询问并定期清除它。如果在主线程询问之间没有再次设置布尔值,则可以推断它已经死亡。

第一种技术的优点是你可以“调整”“合理限制”以容忍代码(在任何一个线程中),它在时间上有些不规则。第二种方法通常需要更可预测的时间。

当然,无论采用哪种方法,如果背景线程刚刚完成并且你还没有意识到,那么你想以某种方式避免“吹口哨”。

答案 1 :(得分:1)

一种常见的技术是有一个额外的线程来检查有问题的线程的生命体征 - 一个所谓的心跳线程。心跳线程通过检查线程是否及时响应来轮询线程,如果没有,则认为线程已死并终止它。

一个简单的心跳线程实现是检查另一个线程定期递增的计数器,如果计数器在一定时间内没有增加它被认为是死的,那么可以采取适当的动作,如重新启动线程或杀死app。另一种更常见的方法是,如果hb线程向线程发送消息并检查具有超时的响应。

答案 2 :(得分:0)

似乎目标c中没有直接检查后台线程状态的机制。提供的任何答案都是不错的选择......要么超时,要么让线程创造某种证据证明其继续存在。

我希望有一些更简单,可靠和实时的东西。

我将尝试在线程中捕获异常,并可能产生前景线程可以监听并做出反应的“BackgroundThreadException”通知。