第一次作业:深入源码分析进程模型

时间:2021-09-02 07:08:52

进程

一.进程是什么?

  1.进程是一个程序在其自身的虚拟地址空间中的一次执行互动,程序本身不占用系统资源。

    2.每一个进程都有一个识别号(PID)

二.在Linux中进程的组成:

  1.进程控制块PCB;

  2.数据段;

    3.正文段。  

    Linux系统为了节省进程控制块所占的内存空间,把每个进程控制块分成两部分。一部分常驻内存,不管进程是否正占有处理器运行,

系统经常会对这部分内容进行查询和处理,常驻部分内容包括:进程状态、优先数、过程特征、数据段始址、等待原因和队列指针等,

这是进行处理器调度时必须使用的一些主要信息。另一部分非常驻内存,当进程不占有处理器时,系统不会对这部分内容进行查询和处理,

因此这部分内容可以存放在磁盘的对换区中,它随用户的程序和数据部分换进或换出内存。

       Linux系统把进程的数据段又划分成三部分:用户栈区(供用户程序使用的信息区);用户数据区(包括用户工作数据和非可重入的程序段);

         系统数据区(包括系统变量和对换信息)。

        正文段是可重入的程序,能被若干进程共享。为了管理可共享的正文段,Linux设置了一张正文表,每个正文段都占用一个表目,

     用来指出该正文段在内存和磁盘上的位置、段的大小以及调用该段的进程数等情况。
 
参考来源:https://blog.csdn.net/baidu_35534327/article/details/54180177
 
三.进程的组织方式:
  1.进程链表

    每个task_struct中都有一个tasks的域来连接到进程链表上去。

           第一次作业:深入源码分析进程模型

 

     以下Init_task的PCB是由编译器预先分配的,在程序运行的过程中一直存在,直到程序结束。

       第一次作业:深入源码分析进程模型
 
  编写以下内核模块,得到所有进程的pid和进程名,并统计出进程总数。
       第一次作业:深入源码分析进程模型
 
  2.哈希表
  使用哈希表来提高查找一个进程的时间复杂度是O(N)的效率。
 
  (1)哈希表的定义:
  第一次作业:深入源码分析进程模型
 
  (2)哈希函数
  第一次作业:深入源码分析进程模型
 
   第一次作业:深入源码分析进程模型
 
     第一次作业:深入源码分析进程模型
 
  第一次作业:深入源码分析进程模型
 
  (3)通过pid查找task_struct
  内核并不能直接通过pid找到对应的task_struct,而是先通过pid找到对应的struct pid,在通过struct pid 找到对应的task_struct。
  
3.就绪队列
  与进程链表类似,task_struct也定义了一个连接到就绪队列的域run_list
  第一次作业:深入源码分析进程模型
 
4.等待队列
  (1)等待队列的数据结构
  第一次作业:深入源码分析进程模型
  task_list链接到等待队列上去。
 
  func是一个函数指针,指向唤醒等待队列中进程的函数。prviate是传递给func的参数,用于指定所要唤醒的进程。
  第一次作业:深入源码分析进程模型
  flags标志进程是否互斥: flags为WQ_FLAG_EXCLUSIVE  时互斥,否则,非互斥。
 
(2)等待队列头
  第一次作业:深入源码分析进程模型  
  lock自旋锁对其进行同步,避免了双向链表被同时访问。task_list是双向链表的节点。
 
(3)等待队列的操作
   i.初始化
  首先,使用了下面的宏声明并初始化了一个等待队列头
  第一次作业:深入源码分析进程模型
 
  如果要对列中一个元素初始化,要使用这个函数:
  第一次作业:深入源码分析进程模型
 
ii:插入/删除
  add_wait_queue()将一个非互斥进程插入到等待队列的第一个位置
  第一次作业:深入源码分析进程模型
 
  add_wait_queue_exclusive()将一个互斥进程插入到等待队列的最后一个位置
 
 
  第一次作业:深入源码分析进程模型
  
  因为非互斥进程不需要临界资源,所以将非互斥进程放在队首,而将互斥进程放在队尾,将它唤醒不会影响其它进程的执行,而互斥进程得到临界资源会导致别的进程无法执行。
 
   remove_wait_queue()将一个进程从等待队列中删除。
  第一次作业:深入源码分析进程模型
  
  iii.检查是否为空队列,直接调用了list.h中的list_empty()
   第一次作业:深入源码分析进程模型
  
  iv.睡眠
  第一次作业:深入源码分析进程模型
 
  v.唤醒
  第一次作业:深入源码分析进程模型
 
  以上参考:https://blog.csdn.net/fdssdfdsf/article/details/7894211
    
四、进程的转换
  转换图如下:
  第一次作业:深入源码分析进程模型  
 
五、进程的调度:
  在 Linux中,进程的运行时间不可能超过分配给他们的时间片,他们采用的是 抢占式多任务处理,所以进程之间的挂起和继续运行无需彼此之间的协作。
  有以下命令:
  i:kill命令
    kill命令是通过向进程发送指定的信号来结束进程的。如果没有指定发送信号,那么默认值为TERM信号。TERM信号将终止所有不能捕获该信号的进程。至于那些可以捕获该信号的进程可能就需要使用kill(9)信号了,该信号是不能被捕捉的。
   ii:nohup命令
    我们一般退出Linux系统时,会把所有的程序全部结束掉,包括那些后台程序。但有时候,例如您正在编辑一个很长的程序,但是您下班或是有事需要先退出系统,这时您又不希望系统把您编辑那么久的程序结束掉,希望退出系统时,程序还能继续执行。这时,我们就可以使用 nohup命令使进程在用户退出后仍继续执行。
  iii:renice命令
    renice命令允许用户修改一个正在运行进程的优先权。 利用renice命令可以在命令执行时调整其优先权。
  注:

  (1) 用户只能对自己所有的进程使用 renice命令。

  (2) root用户可以在任何进程上使用 renice命令。

  (3) 只有root用户才能提高进程的优先权。

  
六、看法理解:
  操作系统对于计算机是十分重要的,其中Linux操作系统是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。在操作系统中,进程又是核心,我们应该更加了解进程的,掌握进程,结合实际,追求更高的效率。