主题优先级 - '单元测试'

时间:2016-06-24 11:23:42

标签: java android multithreading unit-testing

一个非常简洁的问题:如何通过简单测试证明该设置:

android.os.Process.setThreadPriority(int); 

实际上有效吗?

我发布这个问题的原因主要是通用的,因为我找不到一个可以复制的简单测试。

进一步阅读:

对我和我的应用程序来说非常重要,因为它捕获音频,这必须是优先事项。音频数据也被写入文件以及被分析其属性,这不太重要 - 因此我不要求这些任务“真正同时”。

在我的音频帖子中,我设置了:

Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);

我可以通过前后检查简单地测试上面的“已应用”:

Process.getThreadPriority(Process.myTid());

但是,我对测试的需求取决于文档which states

  

最重要的音频线程的标准优先级。应用   通常不能改变这个优先级。

尽管日志输出显示优先级已更改为-19,但我在文档中的措辞引起的担忧是系统在执行时可能不允许正常应用程序的值为-19,它是可能仅为系统应用程序保留?

如果上述情况属实,我想知道如何简单地证明这个优先级值会发生什么 - 它是否默认为允许的最大值,还是可以完全忽略?

关于实际测试本身,我已经尝试了循环和暂停,但没有成功,我不相信我所做的尝试的结果。我也知道这个行为是依赖于操作系统的,所以也许我不能复制一个I've failed to find any upvoted examples的独立Java测试?

希望有人可以提供帮助。提前谢谢。

编辑 - 除了初步答案之外,我确实感谢这种行为可能不是我想要的或期望的。我想要这个实际的物理测试,而不是对可能性的解释。

测试将由多个线程组成,这些线程以不同的优先级运行,并且它们完成的顺序打印到日志中,没有比这更复杂的了。我的尝试似乎过于复杂,因此我在这里寻求帮助。

3 个答案:

答案 0 :(得分:4)

答案:你不能。如果你正在寻找的测试有效,那就不简单了。如果你想要的测试很简单,它就无法工作。

Android不被视为“实时”操作系统,其中优先级保证很难(保证且可靠)而不是软(咨询和仅很荣幸)。在RT O / S中,您可以编写一个简单的测试来评估具有一个高优先级线程和一个低优先级线程的竞争条件,并且此测试将进行确定性评估。在非实时操作系统上,您只能获得统计保证。这意味着你需要一个统计测试,它没有通过简单的标准。然而,统计测试可以是通用的。编写一个运行测试N次的测试工具,并根据某个小于N的阈值传递测试。

但即使设置基础测试并不简单。通常,调度优先级仅在机器在负载下运行时才会起作用,也就是说,当没有足够的CPU来运行时。因此,要设置测试,您需要运行能够淹没CPU的内容;您也可以使用比特币来确保您的流程正在运行。如果这不明显,请计算挖掘尝试而不是成功。谨防过于容易地向操作系统屈服(等待调用)和可以由编译器优化的操作(简单循环)。

设置基本负载后,可以设置高优先级线程。它还需要实际执行某些操作以验证它是否以高优先级运行,因此您也可以在此线程中挖掘比特币。如果此线程以更高的优先级运行,则应在较高优先级线程中的较低优先级线程中获得较高计数。

但你可能不会。由于您不在RT操作系统上,因此大多数情况下您只会获得更高的计数(大概)。如果持续时间太小,您将受制于调度程序的典型持续时间。因此,您可能需要进行一些实验来确定最小持续时间会产生一致的答案。

这种实验并不简单。你不是在RT操作系统上,所以优先级意味着非常模糊。它(几乎可以肯定)没有记录,因此优先级数字的含义是任意的。调度程序如何使用这些优先级数字是他们想要的。例如,可能存在魔术阈值。如果优先级意味着“永不中断;只等待收益”并且您运行的流程不会产生,那么您将挂起机器。由于这些优先级数字可能意味着什么,因此您需要在实践中找出它们的含义,以使您的测试有意义。

所有这些都应该暗示为什么有嵌入式实时操作系统的市场。有时您需要时间保证,当您这样做时,您不应该使用非实时操作系统,即使它很诱人。

答案 1 :(得分:1)

正在测试什么

您运行的CPU具有多个计算单元(核心),可以并行运行。

操作系统有调度点(quanta),它将切换任务,选择(通过一些神秘的逻辑最好的线程来执行下一步。

操作系统具有异步资源访问权限。当尝试从外部设备读取时,它可能: -

  1. 发出请求
  2. 安排不同的主题
  3. 数据可用后重启线程(可能是在量子到期后立即重启)。
  4. Java语言环境可能还有进一步的抽象。

      

    如何通过简单测试证明该设置:   android.os.Process.setThreadPriority(int);   实际上有效吗?

    为了识别在更高优先级的线程上发生更多处理,您需要: -

    1. 确保机器的所有CPU资源都已占用。
    2. 确保您正在测试的内容不需要外部异步设备。
    3. 确保测试持续多个量子。
    4. 确保CPU处于捆绑状态

      如果有备用CPU,那么想要运行的代码可以和将来。因此,测试结果将显示线程优先级之间的边际差异,因为它无关紧要。

      确保测试不需要异步IO

      如果您需要写入设备,此时的间隙将导致您受IO设备的速度驱动而不是线程优先级。

      确保测试具有多个量子

      线程优先级会影响下一个要调度的线程的决定。假定一个线程一旦执行就运行整个量子,然后做出另一个调度决策,那么测试需要测试多个这些决策。

      线程优先级可以有所作为吗?

      由于Android没有声称自己是实时操作系统,因此无法保证线程的最长等待时间为X.(实时操作系统提供的保证)。但是,如果线程已准备好执行(不等待设备或其他异步事件),则可能是高优先级线程将在下一个量程中开始执行。

答案 2 :(得分:0)

继续James Large离开的地方,Android中的线程优先级更多地是对OS任务调度程序的暗示暗示,并且完全依赖于底层的Android OS。 I.E.它可能会尝试为更高优先级的线程提供更多资源,但不保证它。

您在更改优先级时是否在真实设备上进行测试?同样,您不能保证在资源分配方面会尊重您设置的任何优先级,如果日志输出显示优先级更改,我不知道您应该有任何理由不相信它。