Linux内核学习笔记-2.进程管理
原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang
部分内容来自:Linux Kernel Development(Third Edition),Robert Love,陈莉君等译。
1.进程
进程是正在执行的程序代码的实时结果,包含打开的文件、挂起的信号等。线程是进程中的活动的对象,内核调度的对象是线程。在Linux内核对线程与进程并不加以区分,线程只不过是一种特殊的进程。
2.进程描述符
内核把进程的信息存放在task list的双向循环链表中,链表中的每一项都是类型为task_struct、成为进程描述符的的结构,包含一个具体进程的所有信息。Linux通过slab分配器分配task_struct结构,达到对象复用和缓存着色的目的,此时则只需要在栈顶或者栈底创建一个thread_info结构,里面保存task_struct指针。
内核通过一个唯一的进程标识符PID(表示为pid_t隐含类型)来标识每个进程,这个值的类型为int,为了与老版本的Unix和Linux兼容,最大值默认设置为32768(short int的最大值),该上限可以设置。
在内核中,访问任务通常需要获得指向task_struct的指针,通过current宏查找到当前正在运行的进程描述符的的指针(current宏只在内核空间,即内核处于进程上下文时有效)。current宏的实现与硬件体系结构有关,有些硬件体系结构的有专门的寄存器保存当前task_struct指针,但是如x86,并没有这样的寄存器,就只能在内核栈的尾端创建thread_info结构,通过计算偏移简介的查找task_struct指针。方法是,把栈指针的后13个有效位屏蔽掉(假定栈为8KB,):
movl $-8192,%eax
andl %esp,%eax
3.进程状态、上下文、家族树
task_struct中的state描述了进程的当前状态,值必为下列五种状态之一:
1.TASK_RUNNING
运行:正在执行或者在运行队列中等待执行,这是进程在用户空间唯一可能的状态。
2.TASK_INTERRUPTIBLE
可中断:进程阻塞,当进程的某些条件达成或者接收到信号而提前被唤醒,进程可以随时投入运行。
3.TASK_UNINTERRUPTIBLE
不可中断:进程阻塞,但是进程接收信号不会被唤醒,必须在等待时不受干扰或者等待事件很快就会发生。
4.TASK_TRACED
跟踪:被其他进程跟踪的进程。
5.TASK_STOPPED
停止:进程停止运行。
内核通过set_task_state(task,state)设置进程状态。
Linux的进程之间存在明显的继承关系,都是PID为1的init进程的后代。每个task_struct都包含一个指向其父进程名为parent的指针,还包含一个名为children的子进程链表。
4.进程创建
Unix将进程的创建工作分解到两个单独的函数执行:fork()和exec()。
首先,fork()通过拷贝当前进程创建一个子进程,子进程和父进程的区别仅仅在于PID、PPID和某些资源的统计量(对于父进程, fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零)。
exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容。一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号。
在Linux中使用exec函数族主要有两种情况:
1.当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec函数族让自己重生。
2.如果一个进程想执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec,这样看起来就好像通过执行应用程序而产生一个新进程。(这种情况非常普遍)。
Linux的fork()使用写时拷贝(copy-on-write)实现。内核并不复制整个进程地址空间,而是让父进程和子进程共享一个拷贝,资源的复制只有在需要写入的时候才进行,在此之前,以只读方式共享。在页根本不会被写入的情况下(fork()后立即调用exec()),就无须复制了。
5.线程
从内核的角度来说,它并没有线程的概念,Linux把所有的线程当作进程处理,而指定他们共享某些资源。
5.进程终结
进程的析构发生在进程调用exit()系统调用时,极可能显式地调用这个系统调用,也可能从某个程序的主函数返回(c语言编译器会在main函数的返回点后面放之调用exit()的代码)。终结任务大部分靠do_exit()完成。do_exit()完成一系列繁琐的工作,执行后,该进程并非马上消失。
父进程在子进程之前退出,需要保证这些子进程找到一个新的父亲。解决办法是给子进程在当前线程组内找一个线程作为父亲,如果不行,就让init进程领养。
进程终结时的清理工作和进程描述符的删除被分开执行。进程描述符的删除,发生在父进程已经获得已终结的子进程的信息后,或者通知内核它不在关注那些信息后。
wait()系统调用族是通过唯一的系统调用wait4()实现的,标准动作是挂起调用它的进程,由wait()分析当前进程的某个子进程是否退出,wait就会收集这个进程的信息,并把它销毁后返回;如果没有找到,父进程会一直阻塞,直至有一个出现为止。
Linux内核学习笔记-2.进程管理的更多相关文章
- Linux内核学习笔记二——进程
Linux内核学习笔记二——进程 一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...
- Linux学习笔记(六) 进程管理
1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...
- Linux内核学习笔记-1.简介和入门
原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
- linux kernel学习笔记-5内存管理_转
void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...
- 20135316王剑桥Linux内核学习笔记
王剑桥Linux内核学习笔记 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 计算机是如何工作的 个人理 ...
- Linux内核学习笔记(1)-- 进程管理概述
一.进程与线程 进程是处于执行期的程序,但是并不仅仅局限于一段可执行程序代码.通常,进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个 ...
- Linux内核学习笔记——内核内存管理方式
一 页 内核把物理页作为内存管理的基本单位:内存管理单元(MMU)把虚拟地址转换为物理 地址,通常以页为单位进行处理.MMU以页大小为单位来管理系统中的也表. 32位系统:页大小4KB 64位系统:页 ...
- Linux内核入门到放弃-进程管理和调度-《深入Linux内核架构》笔记
进程优先级 硬实时进程 软实时进程 普通进程 O(1)调度.完全公平调度器 抢占式多任务处理(preemptive multitasking):各个进程都分配到一定的时间段可以执行.时间段到期后,内核 ...
- (笔记)Linux内核学习(二)之进程
一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器. 内核调度的对象是线程而不是进程.对 ...
随机推荐
- openNebula libvirt-virsh attach disk device for kvm
1,新建文件硬盘 qemu-img create -f qcow2 testdisk.img 2G
- 截取字符串一之substr
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Spring中注入List,Set,Map,Properties的xml文件配置方法
下面的例子展示了如何注入 List – <list/> Set – <set/> Map – <map/> Properties – <props/> ...
- 几个SQL
select sum(`value`) from testtable where value != 'error' AND type ='b' in (select DISTINCT(type) fr ...
- WPF:向客户端发出某一属性值已更改的通知INotifyPropertyChanged接口
Person.cs using System.ComponentModel; namespace _01_INotifyPropertyChanged { class Person:INotifyPr ...
- R与数据分析旧笔记(十八完结) 因子分析
因子分析 因子分析 降维的一种方法,是主成分分析的推广和发展 是用于分析隐藏在表面现象背后的因子作用的统计模型.试图用最少的个数的不可测的公共因子的线性函数与特殊因子之和来描述原来观测的每一分量 因子 ...
- 1)③爬取网易It方面部分新闻
__author__ = 'minmin' #coding:utf-8 import re,urllib,sgmllib,os #根据当前的url获取html def getHtml(url): pa ...
- 中国 省会 地级市 经纬度 city array
<?php $city_arr = array ( '北京' => array ( 'gis_lng' => '116.405285', 'gis_lat' => '39.90 ...
- python爬虫数据抓取方法汇总
概要:利用python进行web数据抓取方法和实现. 1.python进行网页数据抓取有两种方式:一种是直接依据url链接来拼接使用get方法得到内容,一种是构建post请求改变对应参数来获得web返 ...
- Oracle SQL CPU占用高
Oracle数据库经常会遇到CPU利用率很高的情况,这种时候大都是数据库中存在着严重性能低下的SQL语句,这种SQL语句大大的消耗了CPU资源,导致整个系统性能低下.当然,引起严重性能低下的SQL语句 ...