尽管使用cap_sys_nice

问题描述

我有一个应用程序,可以在POSIX环境下检查是否可以通过调用将线程优先级设置为实时

struct sched_param param;
param.sched_priority = 1;
int canSetRealTimeThreadPriority = (pthread_setschedparam(pthread_self(),SCHED_FIFO,&param) == 0);

一个系统system A上可以使用,但是在另一个system B上则无法通过检查,我想找出原因。

在两个系统上:

  • 通过服务启动脚本将应用程序作为systemd服务启动。

  • 在二进制返回值上getcap调用cap_sys_nice+eip

  • 服务脚本定义应用程序由非root用户通过User=[non root user]

    运行
  • 服务脚本设置LimitRTPRIO=20

  • 调用sysctl -n kernel.sched_rt_runtime_us返回950000,它应该是认值

  • 调用sysctl -n kernel.sched_rt_period_us返回1000000,这应该是认值

  • systemctl show [serviceName]返回LimitRTPRIO=20

  • 调用应用程序(prlimit --pid [application_pid])的运行进程的限制将显示

RESOURCE   DESCRIPTION                             SOFT      HARD UNITS
NICE       max nice prio allowed to raise             0         0
RTPRIO     max real-time priority                    20        20
RTTIME     timeout for real-time tasks        unlimited unlimited microsecs

system B上,它不允许实时线程优先级:

  • etc/security/limits.conf包含行
[non root user]    -    rtprio    20
  • 内核版本为3.10.0-862.el7.x86_64,操作系统版本为Red Hat Enterprise Linux Server release 7.4 (Maipo)

system A上可以设置实时线程优先级的地方:

  • 内核版本为3.10.0-957.56.1.el7.x86_64,操作系统版本为Red Hat Enterprise Linux Server release 7.6 (Maipo)

当我在system A上测试并通过cap_sys_nice+eip从二进制文件删除setcap '' [binary]时,我也无法设置实时线程优先级。我假设system B上的某些设置会覆盖cap_sys_nice设置,因为它具有更高的优先级,所以我想知道那是什么。

解决方法

事实证明,无法在系统范围内设置实时线程优先级的原因是另一个服务正在运行,该服务在服务脚本中定义了以下设置:

CPUShares=20
CPUQuota=500%

从脚本中删除这些设置并重新启动服务后,可以在系统范围内再次设置线程优先级。