Linux系统编程之进程调度问题二

在一中主要介绍了进程的特性值nice的特征和设置问题。接下来主要介绍一下进程的几种调度方式。

	一般系统会同时运行交互进程和后台进程,而标准的内核算法通常能够提供足够的性能和响应度。但通常会有一下几点要求:
  • 需要提供担保最大响应时间。
  • 高优先级进程应该能够保持互斥访问CPU直至它完成或者释放;
  • 实施应用应能够精确的控制其组件进程的调度顺序;//组件进程即从自身fork()出去的进程。

注意:在多处理器(多CPU或者多核)系统中, 高优先级进程 不一定就优先与低优先级的进程,
这里的优先只是相对与申请同一个CPU资源而言,多CPU系统通常可以交叉申请空闲CPU, 这也是为什么多核系统比单核系统运行快的主要原因。

Linux系统大方向有实时和非实时调度策略两种。这其中最大的区别在于实时调度策略允许进程修改优先级, 而非实时调度策略优先级必须为0。

策略 描叙
SCHED_FIFO 实时先入先出
SCHED_RR 实时循环
SCHED_OTHER 标准的循环时间分享
SCHED_OTHER 与SCHED_OTHER类似

SCHED_RR


在这个策略中,优先级相同的进程会以循环时间分享的方式执行,使用CPU的时间为一个固定的时间片。只有满足一下条件才会退出对CPU的使用:

  • 达到时间片终点,进程发送终止信号;
  • 自己放弃CPU(通常是进程阻塞 sched_yield());
  • 终止了;
  • 被一个优先级更高的进程抢占了;//当优先级更高的进程执行结束后, 被抢占的进程会继续执行直到退出(该进程位于同优先级进程的队头);

SCHED_FIFO


先出先入策略和SCHED_RR很相似, 同属于实时调度策略中, 两种最大的区别在与SCHED_FIFO 策略是没有时间片的,也就是说,一旦一个SCHED_FIFO 进程获得了CPU控制权后, 它会一直执行到退出,退出条件与SCHED_RR类似, 只是少了时间片消耗殆尽退出一条。

在实时调度策略中(SCHED_FIFO 和SCHED_RR),可能会因为以下某个原因而被抢占:

  • 之前被阻塞的高优先级进程解除了阻塞;
  • 另一个优先级的进程优先级被提高,并且比当前优先级高;
  • 当前进程优先级被降低了;

----》fork()会继承父进程的调度策略和优先级;

相关API

#include<sched.h>
//获取SCHED_RR策略进程的时间片
int sched_rr_get_interval(pid_t pid, struct timespec *tp);
							return 0 success, or -1 error
//获取优先级取值范围
int sched_get_priority_min(int policy);
int sched_get_priority_max(int policy);
							返回调度策略的优先级取值范围; -1 失败

//设置进程优先级及调度策略
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
							return 0 success, or -1 error
struct sched_param {
    
    
	int sched_priority;  //调度优先级
};
pid :进程的PID
policy:策略参数:SCHED_FIFO ,SCHED_RR等等
param:优先级结构体

int sched_setparam(pid_t pid, const struct sched_param *param);sched_setscheduler()类似, 只是无法设置其调度策略模式;

//获取进程优先级及调度策略
int sched_getscheduler(pid_t pid);			
								返回进程调度策略
int sched_getparam(pid_t pid, const struct sched_param *param);							
								返回进程优先级	

//释放CPU
int sched_yield(void);  //调用此函数后,该进程会放在队列的队尾,如果该优先级队列没有可执行的进程,那么调用该函数不会做任何事,调用进程会继续使用CPU
							return 0 success, or -1 error											

**

防止实时进程锁住系统的几种处理方式

**:

  1. 使用setlimit()设置一个合理的低软CPU时间组员限制,如果进程消耗过多的CPU时间时,会收到一个SIGXCPU信号,该信号会杀死该进程;
  2. 使用alarm()设置一个报警定时器。当进程的运行时间超过设置时间后,该进程会被sigalrm信号杀死;
  3. 创建一个高实时优先级的看门狗进程。该进程可以在指定时间内睡眠,然后醒来监控其他进程;
  4. Linux特殊的非标准资源限制RLIMT_RTTIME

猜你喜欢

转载自blog.csdn.net/huang422600/article/details/103639502