《Linux内核源码分析》(2)进程原理及系统调用

《Linux内核源码分析》(2)进程原理及系统调用

一、进程

  • 操作系统的作用:作为硬件的使用层,提供使用硬件资源的能力,

  • 进程的作用:作为操作系统使用层,提供使用操作系统抽象出的资源层的能力

  • 进程、线程和程序的区别:进程指计算机中已运行的程序。进程本身不是基本的运行单位,而是线程的容器。
    程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行
    实例

  • Linux内核中的进程:Linux内核把进程叫做任务(task),进程的虚拟地址空间可分为用户虚拟地址空间和内核虚拟地址空间,所有进程共享内核虚拟地址空间,每个进程都有独立的用户虚拟空间

  • Linux内核进程的特殊形式:没有用户虚拟地址空间的进程叫内核线程,共享用户虚拟地址空间的进程叫用户线程,共享同一个用户虚拟地址空间的所有用户线程叫线程组

  • C语言标准库进程&Linux内核进程

    C语言标准库进程 Linux内核进程
    包括多个线程的进程 线程组
    只有一个线程的进程 任务或进程
    线程 共享用户虚拟地址空间的进程
  • 查询进程状态

    • ps -aux查询内存中的瞬时进程信息
      《Linux内核源码分析》(2)进程原理及系统调用_第1张图片
      • USER :进程的所属用户,
      • PID :进程的进程ID号,
      • %CPU :进程占用的 CPU资源 百分比,
      • %MEM :进程占用的 物理内存 百分比,
      • VSZ :进程使用掉的虚拟内存量 (Kbytes) ,
      • RSS :进程占用的固定的内存量 (Kbytes) ,
      • TTY :与进程相关联的终端(tty),?代表无关,tty1-tty6是本机上面的登入者程序,pts/0表示为由网络连接进主机的程序。
      • STAT :进程的状态;R->运行->Runnable;S->可中断睡眠->Sleeping;D->不可中断睡眠->Uninterruptible sleep;I->空闲->Idle;Z->僵死->Zombie(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放);T->终止->Terminate;s->进程的领导者;等等…
      • START :进程开始创建的时间 。
      • TIME :进程使用的总cpu时间,
      • COMMAND : 进程对应的实际程序。
    • top动态显示内存中的进程信息
      《Linux内核源码分析》(2)进程原理及系统调用_第2张图片
      • PR : 进程优先级
      • NI : nice 值, 负值表示最高优先级,正值表示 低级优先级
      • VIRT : 进程使用的虚拟内存总量,单位为 KB
      • SHR : 共享内存大小,单位 KB
      • 其他参数在上面已重复提到。

二、进程的生命周期

  • 进程的状态
    • 创建状态:创建新进程
    • 就绪状态:进程获取可以运作所有资源及准备相关条件
    • 执行状态:进程正在CPU中执行操作
    • 阻塞状态:进程因等待某些资源而被跳出CPU
    • 终止状态:进程消亡
  • 进程状态之间的转换
    《Linux内核源码分析》(2)进程原理及系统调用_第3张图片
  • Linux内核通过提供API函数来设置进程的状态
    • TASK_RUNNING:可运行状态或者就绪状态
    • TASK_INTERRUPTIBLE:可中断睡眠状态,又叫浅睡眠状态
    • TASK_UNINTERRUPTIBLE:不可中断状态,又叫深睡眠状态
    • __TASK_STOPPED:终止状态
    • EXIT_ZOMBIE:僵尸状态
  • 通过API表示进程状态转化
    《Linux内核源码分析》(2)进程原理及系统调用_第4张图片

三、task_struct数据结构

  • Linux内核涉及进程和程序的所有算法都围绕一个名为task_struct的数据结构建立,该结构定义在include/linux/sched.h中。task_struct包含很多成员,将进程与各个内核子系统联系起来。下面是Linux5.6.18中关于task_struct结构体的注释。
    《Linux内核源码分析》(2)进程原理及系统调用_第5张图片

四、进程优先级

  • 限期进程的优先级比实时进程高。实时进程的优先级比普通进程高。
    • 限期进程的优先级是-1
    • 实时进程的优先级是1-99,优先级数字越大,表示优先级越高
    • 普通进程的静态优先级为:100-139,优先级数值越小,表示优先级越高,可通过修改nice值改变普通进程的优先级,优先级等于120+nice,很显然:nice值的取值范围是-20~19
  • 各种优先级与进程之间的关系
    • 四种优先级
      在这里插入图片描述
    • 关系对比
      《Linux内核源码分析》(2)进程原理及系统调用_第6张图片

五、系统调用

  • 当运行应用程序的时候,调用fork()vfork()clone()函数就是系统调用。系统调用就是应用程序如何进入内核空间执行任务,程序使用系统调用执行一系列操作:比如创建进程、文件IO等等。具体如下图所示:
    《Linux内核源码分析》(2)进程原理及系统调用_第7张图片

六、内核线程

  • 内核线程是直接由内核本身启动的进程。内核线程实际上是将内核函数委托给独立的进程,与系统中其他进程并发地执行(实际上,也并行于内核自身执行)。内核线程经常称之为(内核)守护进程。他们用于执行下列任务。
    • 周期性地将修改的内存页与页来源块设备同步(例如:使用mmap的文件映射)
    • 如果内存页很少使用,则写入交换区。
    • 管理延时动作(deferred action)。
    • 实现文件系统的事务日志。
  • 内核线程中,task_struct数据结构里面有一个成员指针mm的值为NULL,它只能运行在内核空间。下面是内核创建函数(位于kernel/fork.c):
    /*
     * Create a kernel thread.
     */
    pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
    {
    	struct kernel_clone_args args = {
    		.flags		= ((lower_32_bits(flags) | CLONE_VM |
    				    CLONE_UNTRACED) & ~CSIGNAL),
    		.exit_signal	= (lower_32_bits(flags) & CSIGNAL),
    		.stack		= (unsigned long)fn,
    		.stack_size	= (unsigned long)arg,
    	};
    
    	return _do_fork(&args);
    }
    

七、退出进程

  • 退出进程有两种方式:
    • 进程主动终止:从main()函数返回,链接程序会自动添加到exit()系统调用;或者主动调用exit()系统调用。
    • 进程被动终止:进程收到一个自己不能处理的信号;或者进程收到SIGKILL等终止信息。
  • 下面是退出进程的系统调用,函数位于kernel/exit.c
    SYSCALL_DEFINE1(exit, int, error_code)
    {
    	do_exit((error_code&0xff)<<8);
    }
    

你可能感兴趣的:(Linux内核源码分析,linux,java,运维)