sched_info_depart()

本文介绍了一个内核级函数sched_info_depart,该函数用于在进程失去CPU控制权时更新进程及所属runqueue的CPU使用时间。具体包括:最近一次获得CPU控制权的时间(last_arrival)和进程占用CPU的总时间(cpu_time)。
进程t即将失去CPU控制权
汇总进程t占用CPU的时间总和;进程t所在runqueue占用CPU的时间总和
static inline void sched_info_depart(task_t *t)
{             
    
struct runqueue *rq = task_rq(t);
    unsigned 
long diff = jiffies - t->sched_info.last_arrival;

    t
->sched_info.cpu_time += diff;

    
if (rq)
        rq
->rq_sched_info.cpu_time += diff;
}


task_struct.sched_info.last_arrival     
    when we last ran on a cpu(最近一次获得CPU控制权的时间)
task_struct.sched_info.cpu_time           
    time spent on the cpu
<think>我们正在处理一个关于设置Linux进程调度策略为SCHED_NORMAL的编程问题。根据提供的引用,我们可以知道: - SCHED_NORMAL是Linux中的普通调度策略,即CFS(完全公平调度器),用于普通进程。 - 引用[3]中展示了设置调度策略的系统调用sched_setscheduler的使用,其中需要指定策略(policy)和优先级参数(struct sched_param)。 - 对于实时策略(如SCHED_FIFO和SCHED_RR),优先级范围是1~99,而SCHED_NORMAL(以及SCHED_BATCH、SCHED_IDLE)的优先级必须为0。 因此,要设置进程为SCHED_NORMAL,我们需要: 1. 将policy参数设置为SCHED_NORMAL(在Linux中,SCHED_NORMAL也被定义为SCHED_OTHER,值为0)。 2. 将优先级参数(sched_param结构中的sched_priority)设置为0。 步骤: 1. 包含必要的头文件:<sched.h> 2. 定义一个sched_param结构,并将其sched_priority成员设置为0。 3. 调用sched_setscheduler函数,指定进程ID(0表示当前进程)、策略(SCHED_NORMAL)和参数。 注意:需要具有相应的权限(CAP_SYS_NICE)或者以root用户运行,或者进程的有效用户ID等于目标进程的实际用户ID或保存用户ID(如引用[3]中权限检查部分)。 示例代码: ```c #include <sched.h> #include <stdio.h> #include <unistd.h> int main() { struct sched_param param; param.sched_priority = 0; // 对于SCHED_NORMAL,优先级必须为0 // 设置当前进程的调度策略为SCHED_NORMAL if (sched_setscheduler(0, SCHED_NORMAL, &param) == -1) { perror("sched_setscheduler failed"); return 1; } printf("Scheduling policy set to SCHED_NORMAL successfully.\n"); return 0; } ``` 编译并运行: - 编译:gcc program.c -o program - 运行:./program (可能需要root权限,取决于系统配置) 注意:如果进程之前是实时进程(如SCHED_FIFO或SCHED_RR),将其改为SCHED_NORMAL会使其变为非实时进程,由CFS调度。 相关问题: 1. 如何检查一个进程当前的调度策略? 2. SCHED_NORMAL和SCHED_BATCH有什么区别? 3. 在Linux中,如何以编程方式设置进程的优先级(nice值)? 4. 设置调度策略时,权限不足怎么办?</think>### Linux 设置进程调度策略为 SCHED_NORMAL 的方法 在 Linux 中设置进程调度策略为 `SCHED_NORMAL`(即标准 CFS 调度器)的步骤如下: #### 1. **核心方法** 使用系统调用 `sched_setscheduler()`,将优先级设为 0: ```c #include <sched.h> struct sched_param param = { .sched_priority = 0 // SCHED_NORMAL 必须优先级为0 }; int ret = sched_setscheduler(0, SCHED_NORMAL, &param); ``` - **参数说明**: - `pid`:0 表示当前进程 - `policy`:`SCHED_NORMAL`(或 `SCHED_OTHER`,两者等价) - `param`:优先级结构体,**必须设置 `sched_priority=0`**[^3] #### 2. **完整示例代码** ```c #include <sched.h> #include <stdio.h> #include <unistd.h> int main() { // 设置调度参数 struct sched_param param = { .sched_priority = 0 }; // 修改调度策略 if (sched_setscheduler(0, SCHED_NORMAL, &param) == -1) { perror("sched_setscheduler failed"); return 1; } printf("当前调度策略: %d (SCHED_NORMAL)\n", sched_getscheduler(0)); return 0; } ``` #### 3. **关键注意事项** 1. **权限要求**: - 需要 `CAP_SYS_NICE` 能力(通常需 root 权限) - 或进程有效 UID 与目标进程 UID 匹配[^3] 2. **优先级强制规则**: - `SCHED_NORMAL` 的优先级必须为 0,否则会返回 `-EINVAL` 错误[^3] - 实时策略(`SCHED_FIFO/RR`)优先级范围为 1-99 3. **调度行为变化**: - 从实时策略切回 `SCHED_NORMAL` 后,进程由 CFS 调度器管理 - 可通过 `nice` 值调整 CPU 时间分配比例(范围 -20~19) #### 4. **验证方法** ```bash # 编译程序 gcc sched_normal.c -o sched_normal # 需要root权限执行 sudo ./sched_normal # 查看结果 (应在输出中看到 SCHED_NORMAL) 当前调度策略: 0 (SCHED_NORMAL) ``` #### 5. **与其他策略的区别** | 策略 | 优先级范围 | 调度器 | 适用场景 | |------|------------|--------|----------| | `SCHED_NORMAL` | 固定为 0 | CFS | 普通应用 | | `SCHED_FIFO` | 1-99 | 实时调度器 | 高优先级实时任务[^2] | | `SCHED_RR` | 1-99 | 实时调度器 | 带时间片的实时任务[^2] | > 注:`SCHED_NORMAL` 是 Linux 默认调度策略,适用于 95% 的普通应用场景。实时策略仅建议在严格时限要求的场景(如音视频处理、工业控制)中使用。 --- ### 相关问题 1. **如何将实时进程(`SCHED_FIFO/RR`)切换回普通调度策略?** *(参考本文的代码示例和优先级规则)* 2. **设置调度策略时出现 `Operation not permitted` 错误如何解决?** *(涉及权限配置和能力机制)* 3. `SCHED_NORMAL` 和 `SCHED_BATCH` 调度策略有何区别? *(针对 CPU 密集型任务的优化差异)* 4. **如何以编程方式查询进程当前的调度策略?** *(使用 `sched_getscheduler()` 系统调用)* 5. **在容器(Docker)中设置调度策略有哪些限制?** *(涉及 cgroup 和权能字隔离机制)* [^1]: 设置调度参数示例,包括优先级配置 [^2]: `SCHED_FIFO` 和 `SCHED_RR` 实时调度策略的区别 [^3]: 内核处理函数及权限验证逻辑,强调 `SCHED_NORMAL` 必须优先级为 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值