linux的进程调度算法
饥饿问题
新建进程/时间片结束进程,若放回active,很可能该进程优先级太高,下一个还是执行该进程,导致不断执行同一进程,各进程调度不均衡。
饥饿问题解决
新建进程不能到active,要到expired
时间片到了的进程,也要到expired
这样的话,active中进程只会越来越少
当active为空时,操作系统交换active&expired
struct queue & active & expired
runquequ中有两张struct queue,
struct:queue结构
还有两个struct queue* 成员,active,expired
CPU只会从active中选取进程进行调度
bitmap
int bitmap[5]充当位图
32*5=160 可对应140元素
通过判断bitmap[i]可以一次排查32个位置
这就是linux内核O(1)算法
调度有三种情况
运行退出
不退出,时间片到了
有新进程产生了
调度器要非常均衡地进行进程调度 (目的进程调度算法)
task_struct链接前后节点方式
linux中各task_struct节点之间连接,不是靠task_struct内部直接定义task_struct* next 和task_struct* prev,而是定义一个struct node结构体用来链接前后节点
各结构体类型:
struct node//只有连接字段,没有属性字段
{
struct nide* next;
struct node* prev;
}
struct task_node
{
//...
struct node link//可用来将各task_struct节点连接起来
}
如何做到只有每个进程只有一份task_struct却能同时出现在多个链表中?
task_内部为每个可能出现在的列表定义一个struct node成员以供链接即可
struct task_struct
{
//...其他进程属性
struct node listnode;
struct node queuenode;
struct node waitnode;
//....
}
如何根据struct node*拿到task_struct地址
(struct task_struct* )(&node.next-偏移量)为下一task_struct地址
如何获得struct node*对于task_struct*的偏移量
&((struct node*)0->node.next)即为偏移量
命令行参数
命令行参数传递给main
main函数接受参数
exe运行时传递参数可被main函数接受,main函数根据参数执行不同功能
所以命令行中的命令后接选项实质上是给exe对应的main函数
main参数是谁传递的
参数首先被shell拿到
shell首先按照空格split参数,形成一张表char* argv[] 数组并计算元素个数int argc
shell进程和命令行启动的进程是父子关系
对于数据(尤其是只读),子进程也能看到
所以子进程可从shell中读取argv & argc
CRTstartup
CRTstartup调用main,CRTstartup会检测判断argc
CRTstartup()
{
if(argc==0)
ret =main();
else
ret =main(argc,argv)
}
环境变量
main(int argc,char* argv[],char* env[])
argv与env必以NULL元素结尾
全局变量,key=value
为什么系统自带命令不用./,自己生成的exe运行则不用./?
因为自己生成exe不再user/bin下,而user/bin为环境变量
PATH环境变量告诉了shell去哪里找到exe
shell会从echo $PATH的路径集合中找目标exe来执行
echo $PATH 查看PATH环境变量
env表生成
图片
家目录下.bash_profile与.bashrc为相关配置文件
通过shell中添加PATH,在重启shell时,对PATH的增添会失效。shell