Linux:内核进程     (脑里面必有…

时间:2022-03-13 15:33:55

一.内核进程

程序与进程的区别:

       1.程序是磁盘上的一系列代码和数据的可执行映像,是一个静止的实体.

       2.进程是一个执行中的程序,它是动态的实体.

进程与线程的区别:

       1.进程是分配资源的最小单位.

       2.线程是最小的调度单位.

进程的四要素:

            1.有一段程序供其执行.

            2.专用的内核空间.

             3.有一个task_struct数据结构.

            4.有独立的用户空间堆栈. (主要区别)

 Linux:内核进程     (脑里面必有…

Linux中,线程,进程都是使用struct task_struct来表示包含大量描述线程/进程的信息.

进程描述:

              1.pid_t pid :进程号.

              2.struct mm_struct *mm:用户空间描述指针.内核线程为空.

              3.unsigned int policy:进程调度策略.

              4.int prio:优先级.

               5.intstatic_prio:静态优先级.

              6.struct sched_rt_entity rt.

                 rt->time_slice:时间片.

进程状态:

               1.TASK_RUNNING:进程可执行,准备就绪.  (重要)

               2.TASK_INTERRUPTIBLE:可中断唤醒.      (重要)

               3.TASK_UNINTERRUPTIBLE:不可中断欢喜那个. (重要)

               4.TASK_KILLABLE:Linux2.6.25新引入的,可以SIGKILL唤醒.

                5.TASK_STOPPED:接收SIGSTOP或SIGTSTP等进入阻塞态,当接收SIGCONT

                  重新进入TASK_RUNNING.

               6.TASK_TRACED:处于调试状态.

               7.TASK_DEAD:进程退出.

intexit_state:进程退出时的状态.

EXIT_ZOMBIE:僵死进程,父进程还没发布waitpid()系统调用收集有关死亡的进程的信息.

EXIT_DEAD:僵死撤销状态.进程将由系统删除.

 Linux:内核进程     (脑里面必有…    Linux:内核进程     (脑里面必有…

二. Linux进程调度

调度:从就需的进程中选出最合适的一个来执行.

          1.调度策略.

         2.调度时机.

         3.调度步骤.

调度策略:

               1.SCHED_NORMAL:普通分时进程.  (默认)

               2.SCHED_FIFO:先入先出的实时进程.

               3.SCHED_RR:时间片轮转的实时进程.

               4.SCHED_BATCH:批处理进程.

                5.SCHED_IDLE:只在系统空闲时才能够被调度执行的进程.

调度类:

           CFS调度类:(kernel/sched_fair.c)  1 , 4 ,5

           实时调度类:(kernel/sched_rt.c)  2 ,3

调度时机:

               1. 主动式:调用schedule();

               例子:主动放弃CPU:current->state =TASK_INTERRUPTIBLE;

                                                 schedule();

               2. 被动式:用户抢占. (2.4内核  2.6内核)

                                 内核抢占.(2.6内核)

内核抢占:

不允许:

           1.内核正进行中断处理.

           2.处于中断上下文.

           3.进程正持有spinlock自旋锁,writelock/readlock读写锁等.

           4.正在执行调度程序scheduler().

可能发生在:

                  1.中断处理程序完成,返回内核空间之前.

                  2.当内核代码再一次具有可抢占性的时候

                    例子:解锁and 使能软中断 等.

调度步骤:

               1.清理当前运行中的进程.

               2.选择下一个要运行的进程.  (pick_next_task分析)

               3.设置新进程的运行环境.

               4.进程上下文切换.

 

三. Linux系统调用(2.6.29内核:arch/arm/include/asm/unistd.h)

实现新的系统调用步骤:

                1.添加新的内核函数.

                2.更新头文件unistd.h

                3.针对新函数更改新系统调用表 (call.S)

例子:

1.在kernel/sys.c中添加函数.

asmlinkage int sys_add(int a , intb)

{

    int sum;

    sum = a + b;

    return  sum;

}

//asmlinkage:使用栈传递参数.(汇编程序调用)

 

2.在arch/arm/include/asm/unistd.h中添加如下代码:

#define _ _NR_sys_add     (_ _NR_ SYSCALL_BASE + 361)

361:是内核调用函数的次序,可按实际情况改变.

sys_add:函数名字.

 

3.在arch/arm/kernel/calls.S中添加代码,指向新实现的系统调用函数:

CALL(sys_add)

 

4.重新编译内核.

 

5.使用新实现的系统调用.

#include<stdio.h>

#include<linux/unistd.h>

main()

{

   int sum;

   sum = syscall(361 , 1 , 2);

   printf("sum = %d\n" , sum);

}