zoukankan      html  css  js  c++  java
  • 20169219《Linux内核原理与分析》第八周作业

    网易云课堂学习

    task_struct数据结构

    struct task_struct { 
     volatile long state;进程状态
     void *stack; 堆栈
     pid_t pid; 进程标识符
     unsigned int rt_priority;实时优先级
     unsigned int policy;调度策略
     struct files_struct *files;系统打开文件
     ...
    }
    

    还包括进程链表list_head_tasks,进程ID,进程的父子关系,和CPU相关的进程状态。
    在所有的进程中有三个比较特殊的进程start_kernel,是0号进程;kernel_init,1号进程,它是所有用户态进程的祖先;kthreadd,是2号进程,它是所有内核线程的祖先。0号进程是手动写进去的,1号进程复制了0号进程。
    Linux通过clone()系统调用实现fork()。
    fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建;

    • 进程创建过程为
    • 复制一个PCB——task_struct
    err = arch_dup_task_struct(tsk, orig);
    

    fork()函数调用成功:返回两个值; 父进程:返回子进程的PID;子进程:返回0;
    失败:返回-1;

    fork 创造的子进程复制了父亲进程的资源(写时复制技术),包括内存的内容task_struct内容(2个进程的pid不同)。
    vfork是一个过时的应用,vfork也是创建一个子进程,但是子进程共享父进程的空间。在vfork创建子进程之后,父进程阻塞,直到子进程执行了exec()或者exit()。
    clone是Linux为创建线程设计的(虽然也可以用clone创建进程)。所以可以说clone是fork的升级版本,不仅可以创建进程或者线程,还可以指定创建新的命名空间(namespace)、有选择的继承父进程的内存、甚至可以将创建出来的进程变成父进程的兄弟进程等等。

    • 为子进程初始化
    • 拷贝内核堆栈数据,指定新进程的第一条指令地址。

    使用gdb跟踪分析一个fork系统调用内核处理函数

    设置断点

    子进程是从哪开始执行的?
    从ret_from_fork开始
    分析:首先是fork()函数执行系统调用,调用system_call(),system_call进而根据进程调用号找到sys_fork()函数所在的位置,进而执行sys_fork()函数;之后,sys_fork()函数开始调用do_fork()函数,do_frok()函数位于fork.c文件中,它完成了子进程创建的大部分工作;最后do_fork()函数调用copy_process()函数,copy_process()函数完成了很多工作,比如,为新进程分配内核堆栈,检查进程数目是否超限,区分父、子进程,获取子进程PID等操作。

    Linux内所有进程分配有两种方式:1.通过一个哈希表,由PID值进行哈希计算得到;2. 通过双链循环表实现。

    Linux内核设计与实现

    通过学习了解到系统定时器和时钟中断处理程序是Linux系统内核管理机制的中枢。

    计时中断处理程序会定期地处理以下事务:

    • 更新系统运行时间(uptime)
    • 更新墙上时间(wall time)
    • 在对称多处理器系统(SMP)上,均衡调度各处理器上的运行队列
    • 检查当前进程时间片(time slice)是否耗尽,如果耗尽,则重新调度
    • 运行超时的动态定时器
    • 更新资源耗尽和处理器时间的计算

    内存管理的单位包括字节、页、区。内存分配机制包括页分配器和slab分配器。
    Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。Jeff 的分配器是围绕对象缓存进行的。在内核中,会为有限的对象集(例如文件描述符和其他常见结构)分配大量内存。Jeff 发现对内核中普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间。因此他的结论是不应该将内存释放回一个全局的内存池,而是将内存保持为针对特定目而初始化的状态。例如,如果内存被分配给了一个互斥锁,那么只需在为互斥锁首次分配内存时执行一次互斥锁初始化函数(mutex_init)即可。后续的内存分配不需要执行这个初始化函数,因为从上次释放和调用析构之后,它已经处于所需的状态中了。

    存在 3 种 slab:

    • slabs_full
      完全分配的 slab
    • slabs_partial
      部分分配的 slab
    • slabs_empty
      空 slab,或者没有对象被分配
  • 相关阅读:
    华为云发送邮件
    activiti act_re_model 分析
    tengine upstream
    zuul压力测试与调优
    idea 快捷键
    kubernetes helm
    编写高质量代码–改善python程序的建议(二)
    编写高质量代码--改善python程序的建议(一)
    总结OpenvSwitch的调试经验
    提高SDN控制器拓扑发现性能
  • 原文地址:https://www.cnblogs.com/weihua2616/p/6059758.html
Copyright © 2011-2022 走看看