linux内核进程控制

进程

进程由可执行的指令代码、数据和堆栈区组成,在linux中,除了第一个进程是“手工”建立以外,其余都是进程使用系统调用fork创建的新进程。

Linux系统中,一个进程可以在内核态或者用户态下执行,因此,Linux内核堆栈和用户堆栈是分开的。用户堆栈用于进程在用户态下临时保存调用函数的参数、局部变量等数据。内核堆栈则含有内核程序执行函数调用时的信息。

任务数据结构

内核程序通过进程表对进程进行管理,每个进程在进程表中占有一项,进程表项是一个task_struct任务结构指针。任务数据结构,或者说是进程控制块PCB/进程描述符PD,保存着用于控制和管理进程的所有信息,包括当前运行的状态信息、信号、进程号、父进程号、运行时间累计值、正在使用的文件和本任务的局部描述符以及任务状态段信息。

当一个进程在执行时,CPU中所有寄存器的值、进程的状态以及堆栈中的内容被称为该进程上下文。当切换进程时,需要保存该进程的上下文以便再次执行该进程,能够恢复到切换时的状态执行下去。

进程运行状态

进程的状态保存在进程任务结构的state字段中。


内核态下的运行的进程不能被其他进程抢占,而用户态下可以抢占

进程初始化

当boot/目录中的引导程序把内核从磁盘上加载到内存中,并让系统进入保护模式下运行后,就开始执行系统初始化程序init/main.c。该程序首先确定如何分配使用系统物理内存,然后调用内核各部分的初始化函数分别对内存管理、中断处理、块设备和字符设备、进程管理以及硬盘和软盘硬件进行初始化处理。完成这些操作之后,系统各部分已处于可运行状态。接着程序把自己“手工”通过宏move_to_user_mode移动到进程0中运行,在移动之前,系统在对调度程序的初始化过程中,首先对进程0的运行环境进行设置(包括人工预先设置好进程0数据结构各字段值,在全局描述符表GDT中添加进程0的任务状态段TSS描述符和局部描述符LDT的段描述符,并把它们分别加载到任务寄存器tr和LDT寄存器ldtr中)。进程0也即系统中的第一个进程,并使用fork()函数首次创建出进程1,在进程1中程序将继续进行应用环境初始化并执行shell登录程序。原进程0会在系统空闲时被调度执行。

创建新进程

Linux系统中创建新进程使用fork()函数调用。所有进程都是通过复制进程0而得到的,都是进程0的子进程。

1.系统首先在任务数组中找出一个还没有被任何进程使用的空项。若没有可用空项,即系统可运行进程数目已达上限,会出错返回。

2.系统为新建进程在主内存区中申请一页内存存放其任务数据结构信息,并复制当前进程任务数据结构中的所有内容作为新进程任务数据结构的模板,且设置其状态为不可中断的睡眠状态。

3.对复制的任务数据结构进行修改。把当前进程设置为新进程的父进程,清除信号位图并复位新进程各统计值,并设置初始运行时间片值,再根据当前进程设置任务状态段TSS中各寄存器的值,包括tss.eax,tss.esp0,tss.ss0,tss.ldt。

4.系统设置新进程的代码和数据段基址、限长并复制当前进程内存分页管理的页表

5.在GDT中设置新进程的TSS和LDT描述符项,其中基地址信息指向新进程任务结构中的tss和ldt

6.将新进程设置为可运行状态并返回新进程号。

进程调度

Linux中采用基于优先级排队的调度策略

1.调度程序

1.schedule函数首先扫描任务数组,通过比较每个就绪态进程的运行时间,选择运行时间还不长的进程,并使用任务切换宏函数切换到该进程运行。

2.如果所有处于运行状态的进程时间片都已用完,系统会根据每个进程的优先权值priority,对系统中所有进程重新计算每个进程需要运行的时间片值。

3.schedule()函数重新扫描任务数组所有处于运行状态的,重复上述过程直到选择出一个进程为止

4.调用switch_to()执行进程切换操作

5.如果此时没有其他进程可运行,系统会选择进程0运行。

2.进程切换

switch_to()首先检查要切换到的进程是否为当前进程,如果是则什么也不做,否则执行下述步骤:

1.首先把全局变量current置为新任务的指针,然后长跳转到新进程的任务状态段TSS组成的地址处,造成CPU执行进程切换操作。

2.CPU把其所有寄存器的状态保存到当前任务寄存器TR中的TSS段选择符所指向的当前进程任务数据结构中的tss结构中。

3.把新任务状态段选择符所指向的新任务数据结构中tss结构中的寄存器信息恢复到CPU中,系统正式开始运行新切换的进程

终止进程

1.当一个用户进程调用exit()系统调用时,就会执行内核函数do_exit()。

2.该函数首先释放进程代码段和数据段占用的内存页面,关闭进程打开着的所有文件,对进程使用的当前工作目录、根目录和运行程序的i节点进行同步操作

3.如果进程有子进程,则让init进程作为其所有子进程的父进程

4.如果进程是一个会话头进程并且有控制终端,则释放控制终端,并向属于该会话所有进程发送挂断信号,终止该会话中所有进程,然后把进程置为僵死状态;向父进程发送SIGCHLD信号,通知其某个子进程已经终止

5.最后do_exit()调用调度函数去执行其他进程。

一个用户登录一次系统形成一次会话,创建会话的进程即会话头

进程被终止时,其任务数据结构仍然保留着,因为其父进程还需使用其中的信息

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容