如何确保 NSOperations 以故障安全的方式执行?

发布于 2024-09-13 00:18:14 字数 738 浏览 1 评论 0原文

我想要的

我的应用程序中有一个 NSOperationQueue,在应用程序退出之前处理所有操作至关重要。我在退出时有以下代码,以确保 NSOperationQueue 在退出之前为空:

if ([NSThread isMainThread]) {
    while ([[operationQueue operations] count] > 0) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];
    }
} else {
    [operationQueue waitUntilAllOperationsAreFinished];
}

我之前遇到过代码问题,其中 NSOperation 在完成之前“冻结”并阻塞了整个队列。显然,在这种情况下,我的代码应该抛出异常,现在确实如此。

但我仍然想防止发生任何奇怪的情况,即操作停止并阻塞队列,导致应用程序永远不会退出并且错误不会被捕获。

我的垃圾解决方案

我正在考虑对完成其操作的队列设置超时。然后,当超时时,我可以抛出异常,然后可以捕获问题。

然而,这感觉不对。理想情况下,我不想依赖计时器来确保工作完成。

我的问题

是否有更好的、安全的方法来确保我的操作没有冻结?

What I Want

I've got an NSOperationQueue in my application and it's critical that all operations get processed before the application quits. I've got the following code on quit to make sure the NSOperationQueue is empty before quitting:

if ([NSThread isMainThread]) {
    while ([[operationQueue operations] count] > 0) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];
    }
} else {
    [operationQueue waitUntilAllOperationsAreFinished];
}

I've encountered a problem with my code before where an NSOperation "froze" before finishing and it blocked the whole queue. Obviously, in situations like this, my code should throw an exception, which it now does.

But I still want to guard against anything weird happening where operations stop and block the queue, resulting in the application never quitting and the fault not being caught.

My Rubbish Solution

I'm considering putting a timeout on the queue finishing its operations. Then when it does timeout, I could throw an exception then the problem could be caught.

However, this doesn't feel right. Ideally, I don't want to be reliant upon timers to make sure work is done.

My Question

Is there a better, fail safe, way of making sure my operations haven't frozen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

又爬满兰若 2024-09-20 00:18:14

如果我理解...

  • 您想知道您的操作尚未冻结...变成...
  • 您想知道您的所有操作将完成执行...变成...
  • 您想要解决 停止问题

祝你好运。

但实际上,您使用 waitUntilAllOperationsAreFinished 所做的事情与您将获得的效果差不多。您可以添加另一个类来监视每个操作并确保它不会运行太长时间(比如比您期望的运行时间长 10 倍),此时它将-cancel < code>NSOperation (或多或少是你的计时器方法)。然而,即使这样也不是万无一失的,因为在无法检查 -isCancelled 的地方(例如,在系统调用内部),操作可能会被阻止。

If I understand...

  • you want to know that your operations haven't frozen ... becomes ...
  • you want to know that all of your operations will finish executing ... becomes ...
  • you want to solve the halting problem

Good luck with that.

Realistically though, what you're doing with the waitUntilAllOperationsAreFinished is about as good as you're going to get. You could add another class that watches each operation and makes sure it doesn't run for too long (say 10x longer than you're expecting it to run), at which point it would -cancel the NSOperation (More or less your timer approach). However, even that's not foolproof, because the operation could be blocked on something where you can't check for -isCancelled (inside a system call, for example).

南街九尾狐 2024-09-20 00:18:14

正如 radiospiel 在上面的评论中所说,您实际上并不是在寻找停止问题。如果您可以很好地确定操作长度的上限和下限,则可以为每个操作指定一个时间窗口并查看它们是否已完成。如果你不能做好下界,那么这就会变得低效。另外,如果您的任何操作有无限循环,它们仍然可能导致其他线程挨饿,具体取决于您所处的环境。(那么您就不走运了。)

使用过于广泛的问题概括来将其称为停止问题是计算机科学的经典错误之一。您并不总是需要一般问题。请参阅:http://valgrind.org/

As radiospiel says in comments above, you actually aren't looking for the Halting Problem. If you can do good upper and lower bounds on the length of your operations, you can give each of your operations a time window and see if they've finished. If you can't do good lower bounds, then this becomes inefficient. Also, if any of your operations has an infinite loop, they can still starve the other threads, depending on the environment you are in. (And then you are out of luck.)

Using overly broad generalizations of problems to call them the Halting Problem is one of the classic Computer Science mistakes. You don't always need the general problem. See: http://valgrind.org/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文