在Android平台上如何使用C/C++更改本地线程优先级

15

对于线程优先级而言,pthread的API极其晦涩难懂,不仅如此,它在Android上面也无法使用。

那么,有没有一种方法可以降低或提高线程的优先级呢?

int currentPolicy;
struct sched_param sched;
status = pthread_getschedparam(pthread_self(), &currentPolicy, &sched);
printf("sched.sched_priority:%d currentPolicy:%d", sched.sched_priority, currentPolicy);
printf("priority min/max:%d/%d", sched_get_priority_min(currentPolicy), sched_get_priority_max(currentPolicy));

输出:

sched.sched_priority:0 currentPolicy:0

priority min/max:0/0

无论我做什么,pthread_setschedparam始终会返回一个错误(无效参数)。在我的代码中,我需要降低处理程序线程的优先级,以确保其他线程使用更多CPU时间。或者,作为替代方案,我可以提高我想要用作比进程中其他线程更多CPU的其他线程的线程优先级。

我能否以任何方式实现这一点?我只使用本地c ++代码。

编辑:从此帖子看来,安卓的线程是某种轻量级进程,并且应该使用setpriority修改它们的优先级。它看起来函数是有效的(before和after的getpriority表明已修改优先级)。但是,在我的应用程序中,我没有看到预期的效果。


“...pthread_setschedparam对我总是返回错误(无效参数)。那么您能否告诉我们您传递给函数的参数,以便它返回EINVAL?” - alk
对于 currentPolicy,我尝试传递所有可用值(0、1、2、3)。对于 sched.sched_priority,我尝试设置不同的值(-10、10等),但都失败了。 - Pavel P
3个回答

10

这里是简单的答案:使用int nice(int increment)函数。它在unistd.h中声明。

以下是来自Android的该函数代码:

int nice(int increment)
{
    int  priority = getpriority(PRIO_PROCESS, 0);
    return setpriority( PRIO_PROCESS, 0, priority+increment);
}

那么,setpriority 可以用来设置线程优先级。

实际上,通过使用 nice(-10)nice(10) 在我的代码中得到了预期的差异。


1
我应该把这段代码放在哪里?是线程还是进程?另外,返回值是什么?谢谢。 - RonTLV
就我所知,这个在 <sys/resource.h> 中声明。 - nmr
@nmr 五年前可能不是这样的情况。 - Pavel P
在你最初的问题中,关于 setpriority(),你说:“然而,在我的应用程序中我没有看到预期的效果”,然后你写了自己的答案。使用 setpriority(),你是否真正看到了任何不同? - Jenix
1
@Jenix 我不知道6年前我当时是什么意思 :) 也许我没有正确使用 setpriority。我的答案展示了在安卓上如何运作。 - Pavel P
显示剩余3条评论

10

安卓线程是Linux线程,没有什么特别的。

setpriority()会更改线程的“nice”值,这影响线程调度时的优先级。

pthread_setschedparam()也可以用于更改策略

一般来说,您无法提高优先级或更改其策略而不具备高级权限(CAP_SYS_NICE)。您可以降低它,或将其提高回“正常”优先级。

如果使用adb shell ps -t -p,您可以查看分配给每个线程的优先级。此信息也包含在Dalvik堆栈转储中。

Dalvik使用setpriority()临时提高GC线程的优先级(以避免优先级反转)。如果您查看这段代码,大约在第625行左右,您会看到它。您还可以看到对set_sched_policy()的调用,这是一个Android库函数,用于更改线程所在的cgroup


2
很接近了。在使用setpriority的Android上应该使用nice(int)。其他方法都不起作用。我还尝试搜索整个Android源代码,但没有发现其他函数被使用。 - Pavel P

1

在Android中,无法设置POSIX线程的优先级。 nice()setpriority()函数配置进程的优先级,而不是单个线程的优先级。


1
那是不正确的,我已经亲自验证过了。nice和set-priority(默认)适用于当前进程,在Android本地世界中是一个Linux LWP。你可能会因为优先级被所有启动的线程继承而感到困惑。所以如果在启动子线程/工作线程之前设置优先级,它们都将具有该优先级。 - voidStar
购买并不意味着您可以在创建/运行线程后更改其策略/优先级。 - Remy Lebeau
我同意。无法设置ndk线程的优先级。调用setpriority()与PRIO_PROCESS更改某些优先级(但我不知道是哪个)。在一个简单的测试中,我创建了2个std :: thread,并在其中使用不同的优先级调用setpriority()-它们交替设置自己和其coaleque的优先级。 - Constantin Geier
Linux实现的setpriority与POSIX标准不同,它改变的是线程优先级而不是进程优先级。这个差异在Linux手册的“Bugs”部分中有所说明:https://linux.die.net/man/2/setpriority 我还通过创建多个std::thread,使用pthread_gettid_np将它们的native_handle()转换为线程ID,通过setpriority设置不同的优先级,并通过查看adb shell ps -T -p <pid> -l的NI和PRI列来验证结果。我的优先级更改是针对每个线程而不是整个进程应用的。 - jocopa3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接