ioprio_get 函数详解 链接到标题

1. 函数介绍 链接到标题

ioprio_get 是 Linux 系统中用于获取进程 I/O 优先级的系统调用。可以把 I/O 优先级想象成"进程在磁盘访问队列中的 VIP 等级"——优先级高的进程在访问磁盘时会获得更优先的服务,就像 VIP 客户在银行可以优先办理业务一样。

在多任务系统中,多个进程可能同时需要访问磁盘资源。通过 I/O 优先级机制,系统可以合理分配磁盘带宽,确保重要进程获得足够的 I/O 资源,而低优先级的后台任务不会影响系统整体性能。

2. 函数原型 链接到标题

#include <sys/syscall.h>
#include <linux/ioprio.h>
#include <unistd.h>

int ioprio_get(int which, int who);

注意:ioprio_get 不是标准的 libc 函数,需要通过系统调用使用。

3. 功能 链接到标题

ioprio_get 函数用于获取指定进程或进程组的 I/O 调度优先级。它返回一个编码后的优先级值,包含了调度类和优先级信息。

4. 参数 链接到标题

  • which: 指定要获取优先级的对象类型

    • IOPRIO_WHO_PROCESS: 指定进程
    • IOPRIO_WHO_PGRP: 指定进程组
    • IOPRIO_WHO_USER: 指定用户的所有进程
  • who: 根据 which 参数的具体值

    • 如果 whichIOPRIO_WHO_PROCESS: 进程 ID(0 表示当前进程)
    • 如果 whichIOPRIO_WHO_PGRP: 进程组 ID(0 表示当前进程组)
    • 如果 whichIOPRIO_WHO_USER: 用户 ID(0 表示当前用户)

5. 返回值 链接到标题

  • 成功: 返回编码的 I/O 优先级值
  • 失败: 返回 -1,并设置相应的 errno 错误码

6. 优先级编码 链接到标题

返回值是一个编码后的整数,可以通过以下宏解析:

#define IOPRIO_CLASS_SHIFT 13
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)

#define IOPRIO_PRIO_CLASS(mask) (((mask) >> IOPRIO_CLASS_SHIFT) & 0x7)
#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)

7. 调度类(I/O 优先级类) 链接到标题

类别 说明
IOPRIO_CLASS_RT 1 实时类(最高优先级)
IOPRIO_CLASS_BE 2 尽力而为类(默认)
IOPRIO_CLASS_IDLE 3 空闲类(最低优先级)

8. 优先级数据 链接到标题

对于 IOPRIO_CLASS_BEIOPRIO_CLASS_RT 类,优先级数据范围是 0-7:

  • 0: 最高优先级
  • 7: 最低优先级

9. 相似函数或关联函数 链接到标题

  • ioprio_set: 设置 I/O 优先级
  • nice/getpriority/setpriority: 进程调度优先级
  • ionice: 命令行工具设置/查看 I/O 优先级
  • sched_setscheduler: 设置进程调度策略

10. 示例代码 链接到标题

示例1:基础用法 - 获取当前进程 I/O 优先级 链接到标题

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/ioprio.h>
#include <errno.h>
#include <string.h>

// I/O 优先级相关宏定义
#define IOPRIO_CLASS_SHIFT 13
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPRIO_PRIO_CLASS(mask) (((mask) >> IOPRIO_CLASS_SHIFT) & 0x7)
#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)

// I/O 调度类
#define IOPRIO_CLASS_NONE 0
#define IOPRIO_CLASS_RT 1
#define IOPRIO_CLASS_BE 2
#define IOPRIO_CLASS_IDLE 3

// 获取 I/O 优先级的包装函数
int ioprio_get_wrapper(int which, int who) {
    return syscall(SYS_ioprio_get, which, who);
}

// 设置 I/O 优先级的包装函数
int ioprio_set_wrapper(int which, int who, int ioprio) {
    return syscall(SYS_ioprio_set, which, who, ioprio);
}

// 将调度类转换为字符串
const char* ioprio_class_to_string(int class) {
    switch (class) {
        case IOPRIO_CLASS_NONE: return "NONE";
        case IOPRIO_CLASS_RT:   return "RT (实时)";
        case IOPRIO_CLASS_BE:   return "BE (尽力而为)";
        case IOPRIO_CLASS_IDLE: return "IDLE (空闲)";
        default: return "UNKNOWN";
    }
}

// 显示 I/O 优先级信息
void show_ioprio_info(const char* label, int ioprio) {
    if (ioprio == -1) {
        printf("%s: 获取失败 (%s)\n", label, strerror(errno));
        return;
    }
    
    int class = IOPRIO_PRIO_CLASS(ioprio);
    int data = IOPRIO_PRIO_DATA(ioprio);
    
    printf("%s:\n", label);
    printf("  编码值: 0x%x (%d)\n", ioprio, ioprio);
    printf("  调度类: %s (值: %d)\n", ioprio_class_to_string(class), class);
    
    if (class == IOPRIO_CLASS_BE || class == IOPRIO_CLASS_RT) {
        printf("  优先级: %d (范围: 0-7, 0为最高)\n", data);
    } else if (class == IOPRIO_CLASS_IDLE) {
        printf("  优先级: N/A (空闲类)\n");
    } else {
        printf("  优先级: N/A\n");
    }
    printf("\n");
}

int main() {
    int current_ioprio;
    
    printf("=== I/O 优先级基础示例 ===\n\n");
    
    // 获取当前进程的 I/O 优先级
    current_ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
    show_ioprio_info("当前进程 I/O 优先级", current_ioprio);
    
    // 获取父进程的 I/O 优先级
    int parent_ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, getppid());
    show_ioprio_info("父进程 I/O 优先级", parent_ioprio);
    
    // 获取当前进程组的 I/O 优先级
    int pgrp_ioprio = ioprio_get_wrapper(IOPRIO_WHO_PGRP, 0);
    show_ioprio_info("当前进程组 I/O 优先级", pgrp_ioprio);
    
    // 获取当前用户的 I/O 优先级
    int user_ioprio = ioprio_get_wrapper(IOPRIO_WHO_USER, 0);
    show_ioprio_info("当前用户 I/O 优先级", user_ioprio);
    
    return 0;
}

示例2:I/O 优先级管理和测试 链接到标题

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/ioprio.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>

// I/O 优先级相关宏定义
#define IOPRIO_CLASS_SHIFT 13
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPRIO_PRIO_CLASS(mask) (((mask) >> IOPRIO_CLASS_SHIFT) & 0x7)
#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)

#define IOPRIO_CLASS_NONE 0
#define IOPRIO_CLASS_RT 1
#define IOPRIO_CLASS_BE 2
#define IOPRIO_CLASS_IDLE 3

// I/O 优先级操作包装函数
int ioprio_get_wrapper(int which, int who) {
    return syscall(SYS_ioprio_get, which, who);
}

int ioprio_set_wrapper(int which, int who, int ioprio) {
    return syscall(SYS_ioprio_set, which, who, ioprio);
}

// 编码 I/O 优先级
int ioprio_encode(int class, int data) {
    return (class << IOPRIO_CLASS_SHIFT) | data;
}

// 显示详细 I/O 优先级信息
void display_ioprio_details(const char* context, int ioprio) {
    if (ioprio == -1) {
        printf("%s: 获取失败 (%s)\n", context, strerror(errno));
        return;
    }
    
    int class = IOPRIO_PRIO_CLASS(ioprio);
    int data = IOPRIO_PRIO_DATA(ioprio);
    
    printf("%s:\n", context);
    printf("  原始值: 0x%04x (%d)\n", ioprio, ioprio);
    printf("  调度类: ", class);
    
    switch (class) {
        case IOPRIO_CLASS_NONE:
            printf("NONE (未设置)\n");
            break;
        case IOPRIO_CLASS_RT:
            printf("RT - 实时类 (最高优先级)\n");
            printf("  优先级: %d (0=最高, 7=最低)\n", data);
            break;
        case IOPRIO_CLASS_BE:
            printf("BE - 尽力而为类 (默认)\n");
            printf("  优先级: %d (0=最高, 7=最低)\n", data);
            break;
        case IOPRIO_CLASS_IDLE:
            printf("IDLE - 空闲类 (最低优先级)\n");
            printf("  优先级: N/A (仅在系统空闲时运行)\n");
            break;
        default:
            printf("未知类 (%d)\n");
            break;
    }
    printf("\n");
}

// 测试不同优先级对 I/O 性能的影响
void test_io_priority_impact() {
    const char* test_file = "ioprio_test.dat";
    int fd, ioprio;
    
    printf("=== I/O 优先级影响测试 ===\n");
    
    // 创建测试文件
    fd = open(test_file, O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (fd == -1) {
        perror("创建测试文件失败");
        return;
    }
    
    // 写入测试数据
    char buffer[1024];
    memset(buffer, 0xAA, sizeof(buffer));
    
    for (int i = 0; i < 1000; i++) {
        if (write(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
            perror("写入测试数据失败");
            close(fd);
            return;
        }
    }
    
    close(fd);
    
    // 测试不同优先级
    printf("测试不同 I/O 优先级设置:\n\n");
    
    // 1. 默认优先级
    ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
    display_ioprio_details("默认优先级", ioprio);
    
    // 2. 设置为实时类,高优先级
    int rt_prio = ioprio_encode(IOPRIO_CLASS_RT, 0);
    if (ioprio_set_wrapper(IOPRIO_WHO_PROCESS, 0, rt_prio) == 0) {
        ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
        display_ioprio_details("设置为实时类(最高)", ioprio);
    } else {
        printf("设置实时优先级失败: %s\n\n", strerror(errno));
    }
    
    // 3. 设置为尽力而为类,中等优先级
    int be_prio = ioprio_encode(IOPRIO_CLASS_BE, 4);
    if (ioprio_set_wrapper(IOPRIO_WHO_PROCESS, 0, be_prio) == 0) {
        ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
        display_ioprio_details("设置为尽力而为类(中等)", ioprio);
    } else {
        printf("设置尽力而为优先级失败: %s\n\n", strerror(errno));
    }
    
    // 4. 设置为空闲类
    int idle_prio = ioprio_encode(IOPRIO_CLASS_IDLE, 0);
    if (ioprio_set_wrapper(IOPRIO_WHO_PROCESS, 0, idle_prio) == 0) {
        ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
        display_ioprio_details("设置为空闲类", ioprio);
    } else {
        printf("设置空闲优先级失败: %s\n\n", strerror(errno));
    }
    
    // 恢复默认优先级
    ioprio_set_wrapper(IOPRIO_WHO_PROCESS, 0, ioprio_encode(IOPRIO_CLASS_BE, 4));
    
    // 清理测试文件
    unlink(test_file);
}

// 多进程 I/O 优先级测试
void test_multiprocess_priority() {
    printf("=== 多进程 I/O 优先级测试 ===\n");
    
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        return;
    }
    
    if (pid == 0) {
        // 子进程
        printf("子进程 (PID: %d):\n", getpid());
        
        // 设置子进程为高优先级
        int high_prio = ioprio_encode(IOPRIO_CLASS_RT, 1);
        if (ioprio_set_wrapper(IOPRIO_WHO_PROCESS, 0, high_prio) == 0) {
            int ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
            display_ioprio_details("  子进程优先级", ioprio);
        }
        
        exit(0);
    } else {
        // 父进程
        printf("父进程 (PID: %d):\n", getpid());
        int ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
        display_ioprio_details("  父进程优先级", ioprio);
        
        // 等待子进程结束
        int status;
        waitpid(pid, &status, 0);
    }
}

int main() {
    printf("=== I/O 优先级管理系统 ===\n\n");
    
    // 显示基本进程信息
    printf("基本进程信息:\n");
    printf("  进程 ID: %d\n", getpid());
    printf("  父进程 ID: %d\n", getppid());
    printf("  用户 ID: %d\n", getuid());
    printf("  组 ID: %d\n\n", getgid());
    
    // 获取并显示当前 I/O 优先级
    int current_ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
    display_ioprio_details("当前进程 I/O 优先级", current_ioprio);
    
    // 测试优先级影响
    test_io_priority_impact();
    
    // 多进程测试
    test_multiprocess_priority();
    
    // 显示系统信息
    printf("=== 系统 I/O 调度信息 ===\n");
    printf("可用的 I/O 调度器:\n");
    system("cat /sys/block/sda/queue/scheduler 2>/dev/null || echo '无法读取调度器信息'");
    
    printf("\n=== I/O 优先级使用建议 ===\n");
    printf("1. 实时类 (RT): 关键业务应用,需要及时响应\n");
    printf("2. 尽力而为类 (BE): 默认选择,适合大多数应用\n");
    printf("3. 空闲类 (IDLE): 后台任务,不影响前台应用\n");
    printf("\n使用 ionice 命令行工具:\n");
    printf("  ionice -c 1 -n 0 command    # 实时类,最高优先级\n");
    printf("  ionice -c 2 -n 4 command    # 尽力而为类,中等优先级\n");
    printf("  ionice -c 3 command         # 空闲类\n");
    
    return 0;
}

示例3:完整的 I/O 优先级监控和管理系统 链接到标题

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/ioprio.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <pwd.h>
#include <grp.h>

// I/O 优先级相关宏定义
#define IOPRIO_CLASS_SHIFT 13
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPRIO_PRIO_CLASS(mask) (((mask) >> IOPRIO_CLASS_SHIFT) & 0x7)
#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)

#define IOPRIO_CLASS_NONE 0
#define IOPRIO_CLASS_RT 1
#define IOPRIO_CLASS_BE 2
#define IOPRIO_CLASS_IDLE 3

// 系统调用包装函数
int ioprio_get_wrapper(int which, int who) {
    return syscall(SYS_ioprio_get, which, who);
}

int ioprio_set_wrapper(int which, int who, int ioprio) {
    return syscall(SYS_ioprio_set, which, who, ioprio);
}

// 编码/解码函数
int ioprio_encode(int class, int data) {
    return (class << IOPRIO_CLASS_SHIFT) | data;
}

// 获取类名
const char* get_class_name(int class) {
    switch (class) {
        case IOPRIO_CLASS_NONE: return "NONE";
        case IOPRIO_CLASS_RT:   return "RT";
        case IOPRIO_CLASS_BE:   return "BE";
        case IOPRIO_CLASS_IDLE: return "IDLE";
        default: return "UNKNOWN";
    }
}

// 获取详细类描述
const char* get_class_description(int class) {
    switch (class) {
        case IOPRIO_CLASS_NONE: return "未设置";
        case IOPRIO_CLASS_RT:   return "实时类 - 最高优先级";
        case IOPRIO_CLASS_BE:   return "尽力而为类 - 默认优先级";
        case IOPRIO_CLASS_IDLE: return "空闲类 - 最低优先级";
        default: return "未知";
    }
}

// 显示单个进程的 I/O 优先级
void show_process_ioprio(int pid) {
    int ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, pid);
    if (ioprio == -1) {
        printf("PID %d: 获取失败 (%s)\n", pid, strerror(errno));
        return;
    }
    
    int class = IOPRIO_PRIO_CLASS(ioprio);
    int data = IOPRIO_PRIO_DATA(ioprio);
    
    printf("PID %6d: [%-4s] ", pid, get_class_name(class));
    
    if (class == IOPRIO_CLASS_BE || class == IOPRIO_CLASS_RT) {
        printf("优先级 %d", data);
    } else if (class == IOPRIO_CLASS_IDLE) {
        printf("空闲模式");
    } else {
        printf("未设置");
    }
    
    printf(" - %s\n", get_class_description(class));
}

// 显示用户所有进程的 I/O 优先级
void show_user_processes_ioprio(uid_t uid) {
    struct passwd *pwd = getpwuid(uid);
    if (pwd) {
        printf("用户 %s (UID: %d) 的进程 I/O 优先级:\n", pwd->pw_name, uid);
    } else {
        printf("UID %d 的进程 I/O 优先级:\n", uid);
    }
    
    // 简化实现,实际应用中需要扫描 /proc
    int ioprio = ioprio_get_wrapper(IOPRIO_WHO_USER, uid);
    if (ioprio != -1) {
        int class = IOPRIO_PRIO_CLASS(ioprio);
        printf("  用户默认优先级: [%s] %s\n", 
               get_class_name(class), get_class_description(class));
    }
}

// 设置进程 I/O 优先级
int set_process_ioprio(int pid, int class, int priority) {
    int ioprio = ioprio_encode(class, priority);
    int result = ioprio_set_wrapper(IOPRIO_WHO_PROCESS, pid, ioprio);
    
    if (result == 0) {
        printf("成功设置 PID %d 的 I/O 优先级为 [%s] %d\n", 
               pid, get_class_name(class), priority);
    } else {
        printf("设置 PID %d 的 I/O 优先级失败: %s\n", pid, strerror(errno));
    }
    
    return result;
}

// 显示帮助信息
void show_help(const char *program_name) {
    printf("用法: %s [选项]\n", program_name);
    printf("\n选项:\n");
    printf("  -p, --pid=PID          显示指定进程的 I/O 优先级\n");
    printf("  -u, --user=UID         显示指定用户的所有进程优先级\n");
    printf("  -s, --set=CLASS:PRIO   设置当前进程的 I/O 优先级\n");
    printf("  -a, --all              显示所有相关信息\n");
    printf("  -h, --help             显示此帮助信息\n");
    printf("\n优先级类:\n");
    printf("  rt     - 实时类 (0-7, 0为最高)\n");
    printf("  be     - 尽力而为类 (0-7, 0为最高)\n");
    printf("  idle   - 空闲类\n");
    printf("\n示例:\n");
    printf("  %s -p 1234             # 显示 PID 1234 的优先级\n");
    printf("  %s -s rt:0             # 设置当前进程为实时类最高优先级\n");
    printf("  %s -u 1000             # 显示 UID 1000 用户的进程优先级\n");
}

int main(int argc, char *argv[]) {
    int show_all = 0;
    int target_pid = -1;
    uid_t target_uid = -1;
    char *set_priority = NULL;
    
    // 解析命令行参数
    static struct option long_options[] = {
        {"pid",    required_argument, 0, 'p'},
        {"user",   required_argument, 0, 'u'},
        {"set",    required_argument, 0, 's'},
        {"all",    no_argument,       0, 'a'},
        {"help",   no_argument,       0, 'h'},
        {0, 0, 0, 0}
    };
    
    int c;
    while (1) {
        int option_index = 0;
        c = getopt_long(argc, argv, "p:u:s:ah", long_options, &option_index);
        
        if (c == -1)
            break;
            
        switch (c) {
            case 'p':
                target_pid = atoi(optarg);
                break;
            case 'u':
                target_uid = atoi(optarg);
                break;
            case 's':
                set_priority = optarg;
                break;
            case 'a':
                show_all = 1;
                break;
            case 'h':
                show_help(argv[0]);
                return 0;
            case '?':
                return 1;
        }
    }
    
    printf("=== I/O 优先级监控和管理系统 ===\n\n");
    
    // 处理设置优先级请求
    if (set_priority) {
        char class_str[16];
        int priority = 0;
        int class;
        
        if (sscanf(set_priority, "%[^:]:%d", class_str, &priority) == 2 ||
            sscanf(set_priority, "%[^:]", class_str) == 1) {
            
            if (strcasecmp(class_str, "rt") == 0) {
                class = IOPRIO_CLASS_RT;
            } else if (strcasecmp(class_str, "be") == 0) {
                class = IOPRIO_CLASS_BE;
            } else if (strcasecmp(class_str, "idle") == 0) {
                class = IOPRIO_CLASS_IDLE;
                priority = 0;
            } else {
                fprintf(stderr, "错误: 未知的优先级类 '%s'\n", class_str);
                return 1;
            }
            
            if (priority < 0 || priority > 7) {
                fprintf(stderr, "错误: 优先级必须在 0-7 范围内\n");
                return 1;
            }
            
            set_process_ioprio(0, class, priority);
        } else {
            fprintf(stderr, "错误: 优先级格式应为 CLASS:PRIORITY\n");
            return 1;
        }
        
        printf("\n");
    }
    
    // 显示指定 PID 的优先级
    if (target_pid != -1) {
        show_process_ioprio(target_pid);
        printf("\n");
    }
    
    // 显示指定用户的优先级
    if (target_uid != -1) {
        show_user_processes_ioprio(target_uid);
        printf("\n");
    }
    
    // 显示所有信息
    if (show_all || (target_pid == -1 && target_uid == -1 && !set_priority)) {
        printf("当前进程信息:\n");
        show_process_ioprio(getpid());
        printf("\n");
        
        printf("父进程信息:\n");
        show_process_ioprio(getppid());
        printf("\n");
        
        printf("当前用户信息:\n");
        show_user_processes_ioprio(getuid());
        printf("\n");
        
        // 显示系统 I/O 调度信息
        printf("系统 I/O 调度器信息:\n");
        system("ls /sys/block/ 2>/dev/null | head -3 | while read dev; do "
               "echo \"  $dev: $(cat /sys/block/$dev/queue/scheduler 2>/dev/null || echo 'N/A')\"; done "
               "2>/dev/null || echo '  无法获取调度器信息'");
    }
    
    // 显示使用建议
    printf("\n=== I/O 优先级使用指南 ===\n");
    printf("优先级类说明:\n");
    printf("  RT (实时类):     最高优先级,适合关键业务\n");
    printf("  BE (尽力而为):   默认优先级,适合大多数应用\n");
    printf("  IDLE (空闲类):   最低优先级,仅在系统空闲时运行\n");
    printf("\n建议:\n");
    printf("  1. 数据库、Web服务器等关键服务使用 RT 类\n");
    printf("  2. 普通应用使用 BE 类(默认)\n");
    printf("  3. 备份、压缩等后台任务使用 IDLE 类\n");
    printf("  4. 避免过多进程使用 RT 类,可能影响系统响应\n");
    
    return 0;
}

编译和运行说明 链接到标题

# 编译示例程序
gcc -o ioprio_get_example1 example1.c
gcc -o ioprio_get_example2 example2.c
gcc -o ioprio_get_example3 example3.c

# 运行示例
./ioprio_get_example1
./ioprio_get_example2
./ioprio_get_example3 --help
./ioprio_get_example3 -a
./ioprio_get_example3 -p 1
./ioprio_get_example3 -s rt:0

命令行工具配合使用 链接到标题

# 使用 ionice 命令行工具
ionice                    # 显示当前进程优先级
ionice -p $$             # 显示当前 shell 的优先级
ionice -c 1 -n 0 command # 以实时类最高优先级运行命令
ionice -c 2 -n 4 command # 以尽力而为类中等优先级运行命令
ionice -c 3 command      # 以空闲类运行命令

# 查看进程 I/O 优先级
ionice -p <PID>

# 批量查看进程优先级
ps -eo pid,comm | while read pid comm; do 
    echo "PID $pid ($comm): $(ionice -p $pid 2>/dev/null || echo 'N/A')"
done

系统要求检查 链接到标题

# 检查内核版本(需要 2.6.13+)
uname -r

# 检查 I/O 调度器支持
ls /sys/block/sda/queue/scheduler

# 查看当前进程的 I/O 优先级
cat /proc/$$/io  # I/O 统计信息

重要注意事项 链接到标题

  1. 内核版本: 需要 Linux 2.6.13+ 内核支持
  2. 权限要求: 通常需要适当权限才能修改其他进程的优先级
  3. 调度器支持: 实际效果取决于使用的 I/O 调度器
  4. 继承性: 子进程继承父进程的 I/O 优先级
  5. 错误处理: 始终检查返回值和 errno

实际应用场景 链接到标题

  1. 数据库系统: 提高数据库 I/O 优先级
  2. Web 服务器: 确保 Web 服务响应及时
  3. 备份系统: 将备份任务设置为低优先级
  4. 实时应用: 关键实时任务使用高优先级
  5. 系统管理: 平衡系统资源使用

优先级类详细说明 链接到标题

// I/O 优先级类的实际应用
void explain_priority_classes() {
    printf("I/O 优先级类应用场景:\n");
    printf("1. IOPRIO_CLASS_RT (实时类):\n");
    printf("   - 数据库系统\n");
    printf("   - 实时音视频处理\n");
    printf("   - 关键业务应用\n");
    printf("   - 需要最低延迟的服务\n\n");
    
    printf("2. IOPRIO_CLASS_BE (尽力而为类):\n");
    printf("   - 默认选择\n");
    printf("   - 大多数应用程序\n");
    printf("   - 用户交互式应用\n");
    printf("   - 平衡性能和公平性\n\n");
    
    printf("3. IOPRIO_CLASS_IDLE (空闲类):\n");
    printf("   - 后台批处理任务\n");
    printf("   - 系统维护脚本\n");
    printf("   - 日志归档\n");
    printf("   - 不影响用户体验的任务\n");
}

最佳实践 链接到标题

// 安全地设置 I/O 优先级
int safe_set_ioprio(int class, int priority) {
    // 验证参数
    if (class < IOPRIO_CLASS_RT || class > IOPRIO_CLASS_IDLE) {
        errno = EINVAL;
        return -1;
    }
    
    if (priority < 0 || priority > 7) {
        errno = EINVAL;
        return -1;
    }
    
    // 避免过度使用实时类
    if (class == IOPRIO_CLASS_RT && priority == 0) {
        printf("警告: 设置最高实时优先级可能影响系统稳定性\n");
    }
    
    int ioprio = ioprio_encode(class, priority);
    return ioprio_set_wrapper(IOPRIO_WHO_PROCESS, 0, ioprio);
}

// 获取并验证 I/O 优先级
int get_and_validate_ioprio() {
    int ioprio = ioprio_get_wrapper(IOPRIO_WHO_PROCESS, 0);
    if (ioprio == -1) {
        return -1;
    }
    
    int class = IOPRIO_PRIO_CLASS(ioprio);
    int data = IOPRIO_PRIO_DATA(ioprio);
    
    // 验证优先级值的有效性
    if (class >= IOPRIO_CLASS_RT && class <= IOPRIO_CLASS_IDLE) {
        if ((class == IOPRIO_CLASS_BE || class == IOPRIO_CLASS_RT) && 
            (data < 0 || data > 7)) {
            printf("警告: 优先级数据值异常\n");
        }
        return ioprio;
    }
    
    printf("警告: 未知的 I/O 优先级类\n");
    return ioprio;
}

这些示例展示了 ioprio_get 函数的各种使用方法,从基础的优先级获取到完整的优先级管理系统,帮助你全面掌握 Linux 系统中的 I/O 优先级管理机制。