Linux系统学习——进程

    科技2024-04-19  85

    1.进程描述符:

         进程元数据:每个进程都有其描述符。

         每个进程描述符是通过双向链表保存

         创建进程时除了需要分配cpu,内存等资源外还需要在内核的内存空间中维护一个进程描述文件添加到链表上。

        进程描述符:包含进程的状态,线程信息,运行的列表,内存映射信息,父进程,打开的文件,正在处理的信号等

        描述符文件大小是一定的。

    2.进程切换(上下文件切换)

      

     2.1.A进程切换成B进程:

       需要将栈信息其他寄存信息,指数计数器等信息保存到进程描述文件中,进程描述文件由内核维护,所以最终是保存在内核中。A进入挂起。 

       B进程恢复,将栈指针,指数计数器计入cpu中。

      2.2. 进程切换是由内核完成,所以需要由用户空间转到内核模式再到用户模式的切换中,不可能从一个进程到另一个进程,必须内核完成,所以cpu时间需要由内核占用一部分。

    3.进程抢占

    优先高的可以抢占优先级低的进程的cpu时间。

    3.1.什么时候抢占

    根据cpu的时钟(cpu频率)来抢占。每次时钟来了就可以抢占了。

    3.2.进程饥饿

    进程优先级高的始终通过抢占在运行,就会造成进程优先级低的始终运行不了。

    3.3.进程类别

          交互式进程(I/O)

          批处理进程 (CPU)

          实时进程(Real-time)

    如何决定哪个进程优先级:

    策略:cpu:时间片长,优先级低, I/O:时间片短,优先高

    3.4.优先级如何定义:

     linux进程有三类:

        实时 优先级RT(通常跟内核相关):1-99 数字越小,优先级越低 

        静态优先级(通过跟用户相关):100-139:数据越小,优先级越高

        所以所有的实时优先级都比静态优先级高。

      20是指静态优先级(100 +20) 表示120

    如何查看进程优先级:  ps -e -o class,rtprio,pri,nice,cmd|grep mysqld

    -e:所有进程

    -o:表示我自定义显示字段

    class:调度类型

    rtprio:实时优先级

    pri:优先级

    nice:调整静态优先级

    nice跟优先级有个对应关系:-20-19   :100-139 

    凡是显示加了中括号的表示内核进程

    4.调度类别

    实时进程:

    调度器:SCHED_FIFO(FF); FIFO:FIRST IN FIRST OUT

                   SCHED_RR(RR); RR:Round Robin

                   SCHED_Other(TS):用来调度用户空间进程的(100-139之间的进程)

    4.1.动态优先级:

          内核会在内部临时调整某些优先级低的进程,主要是针对SCHED_Other调度的进程,监控那些始终没有能执行的进程。

         动态优先级:dynamic priority = max(100, min(static priority-bonus+5,139)); bonus范围:0-10

    4.2.如何手动调整优先级

    对100-139间的优先级使用nice, renice

                 启动进程 时: nice n command

                 已经启动的进程:   renice -n #pid

                                            chrt -p [prio] PID

    1-99的进程优先级:

                 已经启动的进程:  chrt -f -p [prio] PID

                                                chrt -r -p [prio] PID

                   启动进程: chrt -f -p [prio] cdmmand

    4.3.内核首先运行优先级高的进程 

    将所有进程按1-139优先级分成139个队列,按优先级排队高到低(这样挑选优先级的进程时间就会大大减少),每个优先级队列有两个,一个是活动队列,一个是过期队列(两个队列轮换),这就是o(1)算法。

     5.进程地址空间

        

    栈:地址从高到低

    堆:地址从低到高

    6.linux如何创建一个进程

    init第一个进程:Kernel生成init,然后每个进程都是由init进程fork()产生,由系统调用。新的进程刚开始创建时内存地址空间与父进程指向同一个,只有在子进程在需要写入时才创建自己的内存空间(Copy On Write)

     

     

     

     

     

     

     

                 

       

     

     

     

     

     

    Processed: 0.021, SQL: 9