IOPRIO_SET - Linux手册页
Linux程序员手册 第2部分
更新日期: 2019-03-06
名称
ioprio_get,ioprio_set-获取/设置I / O调度类和优先级
语法
int ioprio_get(int which, int who); int ioprio_set(int which, int who, int ioprio);
注意:这些系统调用没有glibc包装器。请参阅注释。
说明
ioprio_get()和ioprio_set()系统调用获取并设置一个或多个线程的I / O调度类和优先级。
which和who参数标识系统调用在其上运行的线程。 which参数确定如何解释谁,并具有以下值之一:
- IOPRIO_WHO_PROCESS
- 谁是标识单个进程或线程的进程ID或线程ID。如果谁是0,则在调用线程上进行操作。
- IOPRIO_WHO_PGRP
- 谁是进程组ID,用于标识进程组的所有成员。如果谁是0,则在调用方为其成员的进程组上进行操作。
- IOPRIO_WHO_USER
- 谁是用户ID,用于标识所有具有匹配实际UID的进程。
如果在调用ioprio_get()时将其指定为IOPRIO_WHO_PGRP或IOPRIO_WHO_USER,并且有多个进程匹配谁,则返回的优先级将是所有匹配进程中找到的最高优先级。如果一个优先级属于较高优先级类别(IOPRIO_CLASS_RT为最高优先级类别; IOPRIO_CLASS_IDLE为最低优先级),或者与另一个进程属于同一优先级类别,但优先级较高,则称该优先级高于另一个优先级(较低的优先级数字表示较高的优先级)。
提供给ioprio_set()的ioprio参数是一个位掩码,它指定调度类和要分配给目标进程的优先级。以下宏用于组合和分解ioprio值:
- IOPRIO_PRIO_VALUE(class, data)
- 给定调度类和优先级(数据),此宏将两个值组合以产生ioprio值,该值将作为宏的结果返回。
- IOPRIO_PRIO_CLASS(mask)
- 给定掩码(ioprio值),此宏将返回其I / O类组件,即IOPRIO_CLASS_RT,IOPRIO_CLASS_BE或IOPRIO_CLASS_IDLE值之一。
- IOPRIO_PRIO_DATA(mask)
- 给定掩码(ioprio值),此宏返回其优先级(数据)组件。
有关调度类和优先级以及将ioprio指定为0的含义,请参见NOTES部分。
读取和同步(O_DIRECT,O_SYNC)写入均支持I / O优先级。不支持异步写入的I / O优先级,因为它们是在弄脏内存的程序上下文之外发出的,因此特定于程序的优先级不适用。
返回值
成功时,ioprio_get()返回与在哪个和谁中指定的条件匹配的任何进程中具有最高I / O优先级的进程的ioprio值。如果出错,则返回-1,并且将errno设置为指示错误。
成功时,ioprio_set()返回0。错误时,返回-1,并将errno设置为指示错误。
错误说明
- EINVAL
- 或的无效值。有关ioprio的可用调度程序类和优先级,请参阅"注意"部分。
- EPERM
- 调用进程没有将此ioprio分配给指定进程所需的特权。有关ioprio_set()所需特权的更多信息,请参见NOTES部分。
- ESRCH
- 找不到符合哪个和哪个人的规范的过程。
版本
从内核2.6.13开始,这些系统调用已在Linux上可用。
遵循规范
这些系统调用是特定于Linux的。
备注
Glibc不为这些系统调用提供包装器。使用syscall(2)调用它们。
两个或多个进程或线程可以共享一个I / O上下文。当使用CLONE_IO标志调用clone(2)时就是这种情况。但是,默认情况下,进程的不同线程将不会共享相同的I / O上下文。这意味着,如果要更改进程中所有线程的I / O优先级,则可能需要在每个线程上调用ioprio_set()。此操作所需的线程ID是gettid(2)或clone(2)返回的线程ID。
仅当与支持I / O优先级的I / O调度程序一起使用时,这些系统调用才有效。从内核2.6.17开始,唯一这样的调度程序是完全公平队列(CFQ)I / O调度程序。
如果没有为线程设置任何I / O调度程序,则默认情况下,I / O优先级将跟随CPU优先值(setpriority(2))。在2.6.24版之前的Linux内核中,一旦使用ioprio_set()设置了I / O优先级,就无法将I / O调度行为重置为默认值。从Linux 2.6.24开始,将ioprio指定为0可用于重置为默认的I / O调度行为。
Selecting an I/O scheduler
通过特殊文件/ sys / block // queue / scheduler在每个设备的基础上选择I / O调度程序。
可以通过/ sys文件系统查看当前的I / O调度程序。例如,以下命令显示内核中当前加载的所有调度程序的列表:
$ cat /sys/block/sda/queue/scheduler noop anticipatory deadline [cfq]
用括号括起来的调度程序是该设备实际使用的调度程序(示例中为sda)。设置另一个调度程序是通过将新调度程序的名称写入此文件来完成的。例如,以下命令会将sda设备的调度程序设置为cfq:
$ su Password: # echo cfq > /sys/block/sda/queue/scheduler
The Completely Fair Queuing (CFQ) I/O scheduler
从版本3(也称为CFQ时间片)开始,CFQ实现了类似于CPU调度的I / O级别。这些良好的级别分为三个调度类,每个调度类包含一个或多个优先级:
- IOPRIO_CLASS_RT(1)
- 这是实时I / O类。该调度类的优先级高于任何其他类:此类的进程每次都被赋予对磁盘的首次访问权限。因此,需要格外小心地使用此I / O类:一个I / O实时过程可能会使整个系统饿死。在实时类中,共有8个级别的类数据(优先级),它们确定该过程在每个服务上需要磁盘多少时间。最高实时优先级为0;最低的是7。将来,通过传入所需的数据速率,可能会更直接地映射到性能。
- IOPRIO_CLASS_BE(2)
- 这是尽力而为的调度类,它是任何未设置特定I / O优先级的进程的默认值。类数据(优先级)确定进程将获得多少I / O带宽。尽力而为的优先级类似于CPU的好值(请参阅getpriority(2))。优先级确定相对于尽力而为调度类中其他进程的优先级。优先级范围从0(最高)到7(最低)。
- IOPRIO_CLASS_IDLE(3)
- 这是空闲调度类。仅当没有其他人需要磁盘时,在此级别运行的进程才获得I / O时间。空闲类没有类数据。将优先级类别分配给进程时,需要引起注意,因为如果更高优先级的进程不断访问磁盘,它可能会饿死。
有关CFQ I / O Scheduler和示例程序的更多信息,请参考内核源文件Documentation / block / ioprio.txt。
Required permissions to set I/O priorities
根据两个条件来授予或拒绝更改流程优先级的权限:
- Process ownership
- 非特权进程可以仅为其真实UID与调用进程的真实或有效UID匹配的进程设置I / O优先级。具有CAP_SYS_NICE功能的进程可以更改任何进程的优先级。
- What is the desired priority
- 尝试设置很高的优先级(IOPRIO_CLASS_RT)需要CAP_SYS_ADMIN功能。内核版本高达2.6.24还要求CAP_SYS_ADMIN设置一个非常低的优先级(IOPRIO_CLASS_IDLE),但是自Linux 2.6.25起,就不再需要此设置。
调用ioprio_set()必须遵循这两个规则,否则调用将失败,并显示错误EPERM。
BUGS
Glibc尚未提供合适的头文件,该头文件定义此页面上描述的函数原型和宏。可以在linux / ioprio.h中找到合适的定义。
另外参见
ionice(1),getpriority(2),open(2),功能(7),cgroups(7)
Linux内核源代码树中的Documentation / block / ioprio.txt
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。