进程基本概念

进程基本概念

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与体系结构相关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byd yes

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值