Linux——孤儿进程&进程调度&大O(1)调度

目录

孤儿进程

进程优先级

并行和并发的概念

进程的切换

大O(1)调度队列


只有认知的突破 💫才能带来真正的成长 💫编程技术的学习 💫没有捷径 💫一起加油💫

🍁感谢各位的观看 🍁欢迎大家留言 🍁咱们一起加油 🍁努力成为更好的自己🍁

孤儿进程

概念:父进程比子进程先退出,而此时的子进程为孤儿进程。当子进程完成任务后,就会变为僵尸进程,就会有内存泄漏的风险,为了避免这种情况的发生,该孤儿进程会被1号(init/systemd)进程收养。

代码如下所示:

cpp 复制代码
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
int main() 
{ 
    pid_t id = fork(); 
    if(id < 0){ 
    perror("fork"); 
    return 1; 
    } 
    else if(id == 0){//child 
    printf("I am child, pid : %d\n", getpid()); 
    sleep(10); 
    }else{//parent 
    printf("I am parent, pid: %d\n", getpid()); 
    sleep(3); 
    exit(0); 
    } 
    return 0; 
}

进程优先级

进程的调度是有优先级之分的,不是随意调度的。输入ps -l指令便可查询更加详细的进程信息。如下所示:

  • UID:代表执行者的身份。

  • PID:代表这个进程的代号。

  • PPID:代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号。

  • PRI:代表这个进程可被执行的优先级,其值越小越早被执行。

  • NI:代表这个进程的 nice 值。它用来调节进程的优先级的。

并行和并发的概念

并发:一个队列对应一个CPU。(第一幅图)

并行:多个调度队列对应着多个CPU。(第二幅图)

如下图所示:

进程的切换

CPU上下文切换:在CPU内部有一套寄存器,这套寄存器存储着当前进程的执行信息(比如,代码执行到哪一步了)当该进程被切换掉的时候,该进程会"打包"自己的执行信息(上下文),给存储在自己的struct task_struct信息块里面,等再次被调度的执行的时候,就会把自己的上下文放在CPU这套寄存器里面,CPU就会接着上次的遗留继续执行。

如下所示的结构和内核代码:

大O(1)调度队列

一个CPU对应着一个调度队列------struct runqueue,其结构如下所示:

解释:

在这个调度队列(struct runqueue)中,有三个部分最重要,分别是:*active*expiredarrays[2]。它们三个的类型都为struct prio_array{int nr_active;int bitmap[5];struct list_head}。*active这个指针指向arrays[0]/arrays[1]里面的内容,被*active指向的部分就是运行部分。*expired反之。queue[140]里面存放的是双链表,这个数组的下标就是对应的优先级,所以优先级相同的进程被纳入到对应的双链表队列中。所以OS就可以以O(1)的复杂度直接遍历这个数组就OK了,对于新建的进程和已经执行完的进程,会按照优先级被纳入到过期队列中,当运行队列里面的所有的进程都执行完后,只需要交换active和expired指针变量里面的值就行了,就可以继续执行了。

整体的结构如下所示:

cpp 复制代码
struct rq { 
    spinlock_t lock; 
    /* 
    * nr_running and cpu_load should be in the same cacheline because 
    * remote CPUs use both these fields when doing load calculation. 
    */ 
    unsigned long nr_running; 
    unsigned long raw_weighted_load; 
    #ifdef CONFIG_SMP 
    unsigned long cpu_load[3]; 
    #endif 
    unsigned long long nr_switches; 
    /* 
    * This is part of a global counter where only the total sum 
    * over all CPUs matters. A task can increase this counter on 
    * one CPU and if it got migrated afterwards it may decrease 
    * it on another CPU. Always updated under the runqueue lock: 
    */ 
    unsigned long nr_uninterruptible; 
    unsigned long expired_timestamp; 
    unsigned long long timestamp_last_tick; 
    struct task_struct *curr, *idle; 
    struct mm_struct *prev_mm; 
    struct prio_array *active, *expired, arrays[2]; 
    int best_expired_prio; 
    atomic_t nr_iowait; 
    #ifdef CONFIG_SMP 
    struct sched_domain *sd; 
    /* For active balancing */ 
    int active_balance; 
    int push_cpu; 
    struct task_struct *migration_thread; 
    struct list_head migration_queue; 
    #endif 
    #ifdef CONFIG_SCHEDSTATS 
    /* latency stats */ 
    struct sched_info rq_sched_info; 
    /* sys_sched_yield() stats */ 
    unsigned long yld_exp_empty; 
    unsigned long yld_act_empty; 
    unsigned long yld_both_empty; 
    unsigned long yld_cnt; 
    /* schedule() stats */ 
    unsigned long sched_switch; 
    unsigned long sched_cnt; 
    unsigned long sched_goidle; 
    /* try_to_wake_up() stats */ 
    unsigned long ttwu_cnt; 
    unsigned long ttwu_local; 
    #endif 
    struct lock_class_key rq_lock_key; 
}; 


//**************************************************************************************//
    /* 
    * These are the runqueue data structures: 
    */ 
struct prio_array { 
    unsigned int nr_active; 
    DECLARE_BITMAP(bitmap, MAX_PRIO+1); /* include 1 bit for delimiter */ 
    struct list_head queue[MAX_PRIO]; 
}; 
相关推荐
2401_8920709818 小时前
【Linux C++ 日志系统实战】LogFile 日志文件管理核心:滚动策略、线程安全与方法全解析
linux·c++·日志系统·日志滚动
lwx91485218 小时前
Linux-Shell算术运算
linux·运维·服务器
somi718 小时前
ARM-驱动-02-Linux 内核开发环境搭建与编译
linux·运维·arm开发
双份浓缩馥芮白18 小时前
【Docker】Linux 迁移 docker 目录(软链接)
linux·docker
黄昏晓x19 小时前
Linux ---- UDP和TCP
linux·tcp/ip·udp
路溪非溪19 小时前
Linux驱动开发中的常用接口总结(一)
linux·运维·驱动开发
此刻觐神19 小时前
IMX6ULL开发板学习-01(Linux文件目录和目录相关命令)
linux·服务器·学习
2401_8920709819 小时前
【Linux C++ 日志系统实战】高性能文件写入 AppendFile 核心方法解析
linux·c++·日志系统·文件写对象
航Hang*19 小时前
第3章:Linux系统安全管理——第2节:部署代理服务
linux·运维·服务器·开发语言·笔记·系统安全
-ONLY-¥19 小时前
PostgreSQL运维全攻略:从基础操作到远程配置
linux