• 进程基本概念


    进程基本概念

    1. 进程管理包括哪些内容

    • 进程是怎么创建的?
    • 进程控制块
    • 进程的生命周期
    • 进程切换,如何切换?
    • 进程调度,如何调度?
    • 多核调度,比较难?负载均衡?

    2. linux4.0的task_struct

    2.1 与进程相关的信息

    • state: 用来记录进程的状态
    • pid: 这个是进程唯一的进程标识符(Process Identifier)
    • flag: 用来描述进程属性的一些标志位
    • exit_codeexit_signal :用来存放进程退出值和终止信号,这样父进程可以知道子进程的退出原因。
    • pdeath_signal: 父进程消亡时发出的信号。
    • comm: 存放可执行程序的名称。
    • real_credcred: 用来存放进程的一些认证信息。

    2.2 与调度相关的信息

    • **prio: ** 保存着进程的动态优先级,是调度类优先考虑的优先级。
    • static_prio: 静态优先级。内核不存储nice值,取而代之的是static_prio。
    • normal_prio: 基于static_prio和调度策略计算出来的优先级。
    • rt_priority: 实时进程的优先级。
    • sched_class: 调度类。
    • se: 普通进程调度实体。
    • rt: 试试进程调度实体。
    • dl: deadline进程调度实体。
    • policy: 进程的类型,比如普通进程还是实时进程。
    • cpu_allowed: 进程可以在哪几个CPU上运行。

    2.3 与进程之间的关系

    • real_parent: 指向当前进程的父进程的task_struct数据结构。
    • children: 指向当前进程的子进程的链表。
    • sibling: 指向当前进程的兄弟进程的链表。
    • group_leader: 进程组的组长。

    2.4 与内存管理和文件管理相关信息

    • mm: 指向进程所管理的内存的一个总的抽象的数据结构mm_struct。
    • fs: 保存一个指向文件系统信息的指针。
    • files: 保存一个指向进程的文件描述符表的指针。

    2.5 task_struct总结

    • 进程的运行状态
    • 程序计数器
    • CPU寄存器,保存上下文
    • 内存管理信息
    • 统计信息
    • 文件相关的信息。

    3. 进程的生命周期

    3.1 进程状态

    • 经典操作系统中进程状态图。

    • Linux内核里的进程状态

      #define TASK_RUNNING		0
      #define TASK_INTERRUPTIBLE	1
      #define TASK_UNINTERRUPTIBLE	2
      #define __TASK_STOPPED		4
      #define __TASK_TRACED		8
      /* in tsk->exit_state */
      #define EXIT_DEAD		16
      #define EXIT_ZOMBIE		32
      
      • TASK_RUNNING: 可执行的状态,但是不代表其正在运行。可能是在就绪队列中。所以在Linux中进程的就绪态和运行态是很模糊的,没有明确定义两个宏来表示。

      • TASK_INTERRUPTIBLE: 可中断睡眠状态。当进程等待某个资源时,进程会设置为TASK_INTERRUPTIBLE状态,当可用资源到来时,就设置为TASK_RUNNING状态。

      • TASK_UNINTERRUPTIBLE: 不可中断睡眠状态。当其他进程向其发送信号时,它是没有任何反应的。top、ps命令查看,其是D状态。

      • __TASK_STOPPED: 进程终止。

      • EXIT_DEAD: 进程消亡。

      • EXIT_ZOMBIE: 进程已经消亡了,但是task_struct结构体还没有释放。

    3.2 进程状态设置

    • 进程状态设置

      p->state = TASK_RUNNING;
      

      建议使用Linux提供的API:

      #define set_task_state(tsk, state_value)			\
      do {							\
      	(tsk)->task_state_change = _THIS_IP_;		\
      	set_mb((tsk)->state, (state_value));		\
      } while (0)
      
      #define set_current_state(state_value)			\
      set_mb(current->state, (state_value))
      

    3.3 进程标识符ID

    • 进程标识符PID(Process Identifier): 用来识别进程的唯一号码。

    • PID的类型是一个int类型,所以默认最大值是32768。

    • 为了循环使用PID编号,内核使用bitmap机制来管理当前已经分配的PID编号和空闲的PID编号。

    • getpid()系统调用返回当前进程的tgid值,而不是线程的pid值。

    • 系统调用gettid()会返回线程的PID。

      tgid和pid区别

      posix标准规定:在一个线程组里面,必须使用相同的pid。

      所以给一个组里面发送信号,组里的所有线程都能收到。

    3.4 系统第一个进程是怎么初始化的?

    • 系统中第一个进程的名字有哪些

      • 0号进程
      • idle进程
      • swapper进程
    • 如何获取当前进程的task_struct数据结构?

      • 简单的例子,用sp指针对齐8K,就可以获取struct task_struct结构体。

      • 当前linux内核栈和task_struct之间的关系

        为什么要把struct task_struct从 kernel stack中拧出来?

        原因是struct thread_info大小是固定的,不会随着内核的发展而越来越大,但是struct task_struct结构体可能会越来越大,但是kernel 栈的空间确是固定的,所以留给内核栈的空间就比较多了。

      • linux内核中获取task_struct 的API,ARM64

        register unsigned long current_stack_pointer asm ("sp");
        static inline struct thread_info *current_thread_info(void)
        {
        	return (struct thread_info *)
        		(current_stack_pointer & ~(THREAD_SIZE - 1));
        }
        
        #define get_current() (current_thread_info()->task)
        #define current get_current()
        
      • task_struct和struct thread_info的关系

        • 在进程中常被访问的字段。
        • thread_info与体系结构相关。
  • 相关阅读:
    Linux C应用编程-4-信号
    日志模块loguru 最简单用法
    思科设备EIGRP配置命令
    [CAD二次开发]获取CAD内3D块参照的欧拉旋转交,Matrix3d矩阵转欧拉角。
    Vue项目中,el-image实现按钮触发大图预览模式
    数据库知识点
    TeamTalk梳理概括
    如何让ESP8266板子像APP开发一样方便
    Alibaba Cloud Linux 3.2104 LTS 64位 怎么安装python3.10.12和pip3.10
    TypeScript内置类型有哪些?
  • 原文地址:https://blog.csdn.net/dai_xiangjun/article/details/127042224