2021年12月19日Linux 学习

164 阅读2分钟

进程的调度:

PCB:process control block linux进程控制块
进程创建完成,就会加入到就绪队列中。 
把就绪队列的进程组成一个双向链表,也叫就绪队列。(runqueue),那么这个头就是0号进程,init_task.

进程优先级: 用户空间有两种优先级:数值越小,优先级越高
1.普通优先级(nice) 值是-20 到19.
2.调度优先级(scheduing priority),从1-99.
内核空间优级:动态优先级prio/静态优先级static_prio/归一化优先级normal_prio/实时优先级rt_prio

在没有时间片expired的调度中一般采用的是: 公平调度原则CFS
这里有一个红黑树rbtree,这个红黑树的原则就是通过每个进程的虚拟运行时间(vruntime)来衡量哪个进程最值得被调度。 这个进程的虚拟运行时间是通过进程实际的运行时间和权重weight计算出来的。

sched.h 中对task_struct 定义,里面的重要字段如下:\

volatile long state; //运行状态
unsigned int flags; //运行标记
int prio, static_prio, normal_prio;//优先级相关。动态,静态,普通
unsigned int rt_priority;//实时优先级
unsigned int policy; //进程调度策略
struct sched_info sched_info; //进程运行的统计信息
struct list_head tasks; //这个双向链表,把所有的线程连接到了一起。头部就是0号进程,init_task
struct mm_struct *mm, *active_mm;//线性地址的信息
pid_t pid;
//以下是亲属关系
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/*
* children/sibling forms the list of my natural children
*/
struct list_head children;	/* list of my children */
struct list_head sibling;	/* linkage in my parent's children list */
struct task_struct *group_leader;	/* threadgroup leader */
unsigned long nvcsw, nivcsw; //第一个是主动上下文切换次数,第二个是被动上下文切换次数。
unsigned int irq_events; //中断信息等等
....

atomic_t 原子操作,自动+1. 这种方式的好处就是,一旦发生中断,那么计数就会出错,采用了原子操作,这个计数就保证了同步。读取原子数据的时候使用atomic_read 来读取数据。 一般的计数分为三步:从寄存器中读取数据,+1,最后再写寄存器。 这样三步,如果一旦发生中断,那么计数有可能会出错。

load_monitor负载监视模块: 在系统中,输入uptime 会打印出:
timdembp:linux-imx-4.1.15-2.1.0-gc0de9f6-v1.9 tim$ uptime
23:22  up  4:03, 2 users, load averages: 3.62 4.65 3.33
load averages
后面的三个数代表系统负载在1分钟 5分钟 15分钟的负载情况。

多处理器:主板上有多个cpu
多核处理器:一个cpu 有多个核心。 在linux 中有多少个核心,通过nproc 命令来查看有多少个核心。

参考资料:
www.kerneltravel.net/