【问题标题】:Thread priority - 'unit test'线程优先级 - '单元测试'
【发布时间】:2016-10-27 00:08:33
【问题描述】:

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

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 测试?

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

编辑 - 除了最初的答案,我很感激这种行为可能不是我想要或期望的。我想要实际的物理测试,而不是解释可能性。

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

【问题讨论】:

  • 除非您知道它的含义,否则您无法证明它“有效”。我现在不知道它在 Android 中的具体含义,但在大多数非实时操作系统中,它的含义相当软:类似于,如果两个线程相互竞争 CPU 时间,一个与更高的“优先级”将获得更大的时间份额。但请注意!如果您的测试没有比硬件 CPU 内核更多的可运行线程,那么这些线程实际上不会竞争
  • @jameslarge 我在 Android 设备上看到的最大内核数是 4,网上的数量是 Runtime.getRuntime().availableProcessors() 所以我希望这不会成为问题。
  • 通过单元测试可以做的最好的事情是验证您的应用设置了正确的优先级值。通过集成测试,您可以验证您的应用是否设置了该值,然后(可能)从操作系统检索优先级值并确认它已设置。
  • @DwB 但我可以以不同的优先级运行测试,并且在所有条件相同的情况下,查看它在中间完成的其他线程的优先级
  • 所有这些讨论都让我要求澄清一下。为什么你完全关心优先级?您试图通过设置优先级来避免哪些不良行为?如果你能回答这个问题,你就可以开始考虑如何用定量(换句话说,可测试的)术语来指定你要寻找的东西。

标签: java android multithreading unit-testing


【解决方案1】:

继续 James Large 停止的地方,Android 中的线程优先级更多地是对操作系统任务调度程序的暗示性提示,并且完全依赖于底层 Android 操作系统。 IE。它可能会尝试为更高优先级的线程提供更多资源,但不能保证。

当您更改优先级时,您是在真实设备上进行测试吗?虽然你不能保证你设置的任何优先级在资源分配方面都会得到尊重,但如果日志输出显示优先级发生了变化,我不知道你应该有任何理由不相信它。

【讨论】:

  • 我不喜欢做假设 - 测试会证明行为,因此会提出问题。
  • 但是如果自报Process.getThreadPriority(Process.myTid());对您来说测试还不够,实际测试线程优先级的唯一方法是运行冲突线程。听起来你不喜欢这样做。但 Android 中的线程优先级不是具有确定值的属性
  • 我的问题听起来并不反对——这正是我想要的……测试冲突线程,设置不同的优先级并检查它们完成的顺序。这样我可以确定问题中提到的音频线程优先级的有效性。我会重新阅读我的问题,看看是否需要更改措辞。
  • 哦,我明白了。我不知道在单元测试之类的表单中执行此操作的最简单方法,但我认为您可以设置一些标准测试,例如对提供的列表进行排序,然后创建多个线程,每个线程都分配有不同的优先级.同时启动每个线程,并让它们在完成后以某种方式通知您。如果尊重线程优先级,它们应该按顺序完成。但是您需要确保任务足够复杂,需要重新分配大量资源,并确保您考虑了内核数与线程数。
  • 同意,这正是我所需要的!不过,我的尝试变得过于复杂了……我不想在问题中提到在负载下开始的额外内核,以避免过于复杂!我总是可以在测试中停用除一个以外的所有设备。
【解决方案2】:

回答:你不能。如果您正在寻找的测试有效,那并不简单。如果你想要的测试很简单,那就不行了。

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

但即使设置基础测试也不简单。通常,调度优先级仅在机器负载运行时才重要,也就是说,当没有足够的 CPU 运行时。所以要设置你的测试,你需要运行一些会占用 CPU 的东西;你不妨挖掘比特币以确保你的进程正在运行。如果这不明显,请计算挖掘尝试而不是成功。小心自愿让步给操作系统(等待调用)和编译器可以优化的操作(简单循环)。

设置基本负载后,您可以设置高优先级线程。它还需要实际做一些事情来验证它是否以高优先级运行,所以你也可以在这个线程中挖掘比特币。如果此线程以较高优先级运行,则在较高优先级线程中的某个给定持续时间内,您应该比较低优先级线程获得更高的计数。

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

这种实验并不简单。您不在 RT 操作系统上,所以优先级的含义非常模糊。它(几乎可以肯定)没有记录在案,因此优先级数字的含义是任意的。调度程序如何使用这些优先级数字是他们想要的。例如,可能存在魔法阈值。如果有一个优先级意味着“从不中断;只等待屈服”并且您运行一个不屈服的进程,您将挂起机器。由于这些优先级数字可能意味着任何事情,因此您需要了解它们在实践中的含义,以便使您的测试有意义。

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

【讨论】:

  • 感谢您的回答 - 我很欣赏这些陷阱,但我追求的是物理 测试
  • 我在回答中要说的一件事是,您的问题被严重低估了。在非实时操作系统上,你不能问关于优先级的简单问题。您必须询问适当的行为,并指定比单个整数要复杂得多。
  • 我只能设置一个整数,所以测试肯定不会比这更复杂吗?我的问题不是要求澄清行为,而是要求进行测试,以便我查看行为。
  • 当然比这更复杂。我已经扩展了我的答案以说明原因。
  • 我明白你在解释什么,感谢你的扩展。我真正想要的是一个简单的测试,所以我可以想象你在说什么。如果由于 CPU 负载不足或其他因素而忽略线程优先级,那么请注意 - 但我希望能够针对我的代码在多个测试设备上生成的负载运行这样的测试,所以我可以评估是否需要其他线程方法,比设置优先级更复杂。这个答案没有被赞成,stackoverflow.com/a/37163758/1256219 但它是一个基本测试的例子。
【解决方案3】:

正在测试什么

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

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

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

  1. 发出请求
  2. 安排不同的线程
  3. 在数据可用后重新启动线程(可能立即,也可能在时间片到期后)。

Java 语言环境可能有进一步的抽象。

我如何通过一个简单的测试证明该设置: android.os.Process.setThreadPriority(int); 真的有效吗?

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

  1. 确保计算机已占用所有 CPU 资源。
  2. 确保您正在测试的事物不需要外部异步设备。
  3. 确保测试持续多个量子。

确保 CPU 被占用

如果有空闲的 CPU,那么想要运行的代码就可以并且愿意。所以测试结果会显示线程优先级之间的微小差异,因为这并不重要。

确保测试不需要异步 IO

如果您需要写入设备,那么这段时间的差距将导致您被 IO 设备的速度而不是线程优先级驱动。

确保测试有多个量子

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

线程优先级可以产生影响吗?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 2012-11-17
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 2010-09-22
    相关资源
    最近更新 更多