【问题标题】:How to cancel a task that has native code (C/C++)?如何取消具有本机代码 (C/C++) 的任务?
【发布时间】:2013-01-07 14:39:44
【问题描述】:

背景

我有一个简短而繁重的任务,它使用 NDK (JNI) 来进行一些位图操作。

在某些情况下,我需要取消任务并去做其他事情。

但是,由于任务也占用了大量内存,并且最终还会创建一个大的位图,这可能会导致内存不足的错误。

问题

我应该如何取消包含本机代码的任务?有这方面的最佳做法吗?

也许是某种我可以用于 C/C++ 的中断异常,这样一旦它被捕获,我至少可以释放所有内存?

也许我应该在本机代码中添加某种侦听器(观察者)?或者我应该调用一个我需要假设调用者拥有的方法?

【问题讨论】:

    标签: android android-ndk android-asynctask java-native-interface cancellation


    【解决方案1】:

    最简单的方法?

    在线程上旋转任务。您可以在 Java 中旋转线程并从那里调用 JNI。它比 pthreads 更容易。

    引入一个 volatile 标志(布尔变量),在任务启动时将其设置为 false。

    在任务中,尽可能多地检查停止标志。如果为 true,则放弃任务(您可能会抛出异常以通过多层函数嵌套返回,但您不必这样做)。

    当你想取消时,从主线程设置标志。等待任务注意到这一点。

    如果任务中最慢的部分是调用库/操作系统函数,这将无法正常工作 - 该函数不会检查标志。

    C++ 中没有安全的内置机制来正确终止不想终止的代码线程(可能是信号,但它们会终止整个进程,而不是线程)。定期检查标志就是我所说的“想要被终止”。

    【讨论】:

    • 设置和检查从 java 到 C++ 的标志是否更好/更快(java 调用本机函数在 C++ 和 C++ 检查中设置标志)?还是从 C++ 到 java 更好(C++ 调用 java 函数来检查在 java 中设置的标志)?
    • 常见模式是发出信号线程从外部退出,所以用你的话说它是“java 到 C++”。线程伸手要求退出(所以“C++ 到 java”)是不常见和尴​​尬的,因为你的线程可能会在 java 端被阻塞。此外,特别是对于 JNI 环境,您需要 AttachCurrentThread() 才能进行调用。速度上的差异不值得讨论 IMO。
    【解决方案2】:

    我以前见过这种方法,我认为最好的方法是创建一个isCancelled() 方法,您可以从本机代码定期调用该方法以确定何时停止。如果您使用的是AsyncTask,则该方法应该已经存在。

    【讨论】:

      猜你喜欢
      • 2018-09-05
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多