原创文章,转载请注明: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.进程管理的更多相关文章

  1. Linux内核学习笔记二——进程

    Linux内核学习笔记二——进程   一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...

  2. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  3. Linux内核学习笔记-1.简介和入门

    原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  4. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  5. 20135316王剑桥Linux内核学习笔记

    王剑桥Linux内核学习笔记 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 计算机是如何工作的 个人理 ...

  6. Linux内核学习笔记(1)-- 进程管理概述

    一.进程与线程 进程是处于执行期的程序,但是并不仅仅局限于一段可执行程序代码.通常,进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个 ...

  7. Linux内核学习笔记——内核内存管理方式

    一 页 内核把物理页作为内存管理的基本单位:内存管理单元(MMU)把虚拟地址转换为物理 地址,通常以页为单位进行处理.MMU以页大小为单位来管理系统中的也表. 32位系统:页大小4KB 64位系统:页 ...

  8. Linux内核入门到放弃-进程管理和调度-《深入Linux内核架构》笔记

    进程优先级 硬实时进程 软实时进程 普通进程 O(1)调度.完全公平调度器 抢占式多任务处理(preemptive multitasking):各个进程都分配到一定的时间段可以执行.时间段到期后,内核 ...

  9. (笔记)Linux内核学习(二)之进程

    一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器. 内核调度的对象是线程而不是进程.对 ...

随机推荐

  1. Linux一键安装web环境全攻略(阿里云服务器)

    摘自阿里云服务器官网,此处 一键安装包下载: 点此下载 安装须知 1.此安装包可在阿里云所有linux系统上部署安装,此安装包包含的软件及版本为: nginx:1.0.15.1.2.5.1.4.4 a ...

  2. 关于jquery的each的操作;

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. kafka学习(三)-kafka集群搭建

    kafka集群搭建 下面简单的介绍一下kafka的集群搭建,单个kafka的安装更简单,下面以集群搭建为例子. 我们设置并部署有三个节点的 kafka 集合体,必须在每个节点上遵循下面的步骤来启动 k ...

  4. 存储过程中调用EXECUTE IMMEDIATE的“权限不足”问题

    使用plsql 动态创建表时,用户需要具有create any table 权限 例如: create or replace procedure create_table_test is tmpstr ...

  5. 更改DataTable列名方法

    1.通过DataAdapter将查询的结果填充到DataSet的表(DataTable)中: 如:dataAdapter.Fill(dataSet),这时dataSet的表名默认为Table 如果使用 ...

  6. java中两个对象间的属性值复制,比较,转为map方法实现

    package com.franson.study.util; import java.lang.reflect.InvocationTargetException; import java.lang ...

  7. jQuery Mobile基础

    1.安装 在<head></head>标签里边写入以下内容 jQuery Mobile CDN: <head> <meta charset="utf ...

  8. android之PackageManager简介

    PackageManager相关 本类API是对所有基于加载信息的数据结构的封装,包括以下功能: 安装,卸载应用查询permission相关信息 查询Application相关信息(applicati ...

  9. Android知识简单测试题

    上周去了一场Android考试,前面基础的题目很简单却答不上来,看过跟做过,懂了和会讲差距还是很大的,下面整理一下还记得的几个问题,自勉! 还是觉得,要好好看官方文档才是正道的啊! 1. Androi ...

  10. [Jobdu] 题目1506:求1+2+3+...+n

    题目描述: 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C).  输入: 输入可能包含多个测试样例. 对于每 ...