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、*expired和arrays[2]。它们三个的类型都为struct prio_array{int nr_active;int bitmap[5];struct list_head}。*active这个指针指向arrays0/arrays1里面的内容,被*active指向的部分就是运行部分。*expired反之。queue140里面存放的是双链表,这个数组的下标就是对应的优先级,所以优先级相同的进程被纳入到对应的双链表队列中。所以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]; 
}; 
相关推荐
Felven7 小时前
stress-ng 与 fio 性能测试工具使用指南
linux·测试工具·fio·stress-ng
huainingning8 小时前
RJ SW Console口忘记密码处理方法
linux·运维·服务器
布裘8 小时前
【银河麒麟】桌面系统循环登录,无法进入桌面?
linux·运维·服务器
慧都小项8 小时前
程序到了Linux才出错?用CLion把调试接到目标环境
linux·运维·服务器
Ruiery10 小时前
Linux 6.6内核内存管理深度解析(一):物理内存初始化 — memblock 怎么把内存交给 buddy
linux·运维·服务器
2401_8685347811 小时前
无线网络规划设计
服务器·网络
库拉镜像AI牛牛11 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别
天蓝蓝的本我11 小时前
conda日常用到的命令积累1-登录linux,安装pycharm
linux·pycharm·conda
Android系统攻城狮11 小时前
Linux Gstreamer深度解析之gst_audio_encoder_get_frame_max调用流程与实战(五十九)
linux·运维·服务器·gstreamer音视频·音视频进阶·gstreamer音视频进阶
l1t12 小时前
DeepSeek总结的一个不含数据的 DuckDB 数据库
服务器·数据库·duckdb