操作系统实战 45 讲
彭东
网名 LMOS,Intel 傲腾项目关键开发者
65203 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 60 讲
尝尝鲜:从一个Hello到另一个Hello (2讲)
特别放送 (1讲)
操作系统实战 45 讲
15
15
1.0x
00:00/00:00
登录|注册

24 | 活动的描述:到底什么是进程?

实现进程
进程的结构
什么是进程
感受一下
进程的描述

该思维导图由 AI 生成,仅供参考

你好,我是 LMOS。
在前面的课程里,我们已经实现了数据同步、hal 层的初始化,中断框架、物理内存、内存对象、虚拟内存管理,这些都是操作系统中最核心的东西。
今天,我再给你讲讲操作系统里一个层次非常高的组件——进程,而它又非常依赖于内存管理、中断、硬件体系结构。好在前面课程中,这些基础知识我们已经搞得清清楚楚,安排得明明白白了,所以我们今天理解进程就变得顺理成章。

感受一下

在你看来,什么是进程呢?日常我们跟计算机打交道的时候,最常接触的就是一些应用程序,比如 Word、浏览器,你可以直观感受到它们的存在。而我们却很难直观感受到什么是进程,自然也就不容易描述它的模样与形态了。
其实,在我们启用 Word 这些应用时,操作系统在背后就会建立至少一个进程。虽然我们难以观察它的形态,但我们绝对可以通过一些状态数据来发现进程的存在。
在 Linux 的终端下输入 ps 命令, 我们就可以看到系统中有多少个进程了。如下图所示。
这是进程吗?是的,不过这只是一些具体进程的数据,如创建进程和用户、进程 ID、使用 CPU 的百分比,进程运行状态,进程的建立时间、进程的运行时间、进程名等,这些数据综合起来就代表了一个进程。
也许看到这,你会呵呵一笑,觉得原来抽象的进程背后,不过是一堆数据而已,关于进程这就是我们能直观感受到的东西,这就完了吗?当然没有,我们接着往下看。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了操作系统中一个层次非常高的组件——进程。作者通过比喻的方式让读者感受到进程的存在,并从进程的概念、结构和实现三个方面展开讲解。进程是应用程序运行时刻的实例,是应用程序运行时所需资源的容器,也是一堆数据结构。进程的结构包括地址空间、内核和用户的应用程序部分。文章详细介绍了如何表示一个进程的数据结构,并给出了相应的代码示例。此外,还介绍了进程的机器上下文和建立进程的接口。通过简单易懂的语言和具体的代码示例,帮助读者快速了解了进程的概念、结构和实现。文章内容涉及进程的地址空间、机器上下文以及建立进程的接口,对于想深入了解操作系统进程管理的读者具有很高的参考价值。 文章中还介绍了创建thread_t结构和初始化内核栈的相关操作。通过代码示例和详细解释,读者可以了解如何创建thread_t结构,分配内存并初始化其实例变量。此外,文章还详细介绍了为什么需要初始化进程的内核栈以及如何进行内核栈的初始化操作。通过对进程内核栈的初始化,可以在进程的内核栈中放置一份CPU的寄存器数据,从而实现进程的运行。同时,还介绍了初始化返回进程应用程序空间的内核栈的操作,使读者能够了解如何在内核栈中放置应用程序的代码段和数据段选择子,以便CPU能够返回到进程的应用程序空间。 总之,本文通过具体的代码示例和清晰的解释,帮助读者深入了解了进程的概念、结构和实现,以及创建thread_t结构和初始化内核栈的相关操作,为想深入了解操作系统进程管理的读者提供了宝贵的参考资料。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《操作系统实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • neohope
    置顶
    一、数据结构 thread_t表示一个线程,包括: 锁【并发】、链表 进程标志、进程状态、进程编号【内存地址】、CPU编号【当前全是0】、CPU时间片、进程权限【内核or用户】、优先级【越小越高】、运行模式 栈信息【内核栈、应用栈】,每个进程的栈是独立的,向下生长 内存地址空间信息virmemadrs_t,每个进程的内核部分是共用的,应用部分是独立的,通过页表实现 上下文信息,用于进程切换 进程打开资源的描述符,最多TD_HAND_MAX个 二、新建进程 init_krl->init_krlcpuidle->new_cpuidle->new_cpuidle_thread->krlnew_thread ->krlnew_kern_thread_core新建内核进程 ->krlnew_user_thread_core新建用户进程 krlnew_kern_thread_core: A、krlnew分配内核栈空间 B、krlnew_thread_dsc建立thread_t结构体的实例变量,并初始化 C、设置进程权限,优先级,进程的内核栈顶和内核栈开始地址 D、初始化进程的内核栈 E、加入进程调度系统,sschedcls.scls_schda[cpuid].sda_thdlst[td_priority].tdl_lsth krlnew_user_thread_core: A、krlnew分配应用程序栈空间 B、krlnew分配内核栈空间 C、krlnew_thread_dsc建立thread_t结构体的实例变量,并初始化 D、设置进程权限,优先级,进程的内核栈顶和内核栈开始地址,进程用户栈顶和内核栈开始地址 E、初始化进程的应用栈 F、加入进程调度系统,sschedcls.scls_schda[cpuid].sda_thdlst[td_priority].tdl_lsth 三、中断进程切换【以硬件中断为例】 A、定义了宏HARWINT,其中硬件中断分发器函数为hal_hwint_allocator %macro HARWINT 1 保存现场...... mov rdi, %1 mov rsi,rsp call hal_hwint_allocator 恢复现场...... %endmacro B、定义了各种硬件中断编号,比如hxi_hwint00,作为中断处理入口 ALIGN 16 hxi_hwint00: HARWINT (INT_VECTOR_IRQ0+0) C、有硬件中断时 CPU 会根据中断门描述里的目标段选择子,进行必要的特权级切换; 特权级的切换就必须要切换栈,CPU 硬件会自己把当前 rsp 寄存器保存到内部的临时寄存器 tmprsp; 然后从 x64tss_t 结构体 【地址在GDT表,由 CPU 的 tr 寄存器指向】中找出对应的栈地址,装入 rsp 寄存器中; 接着,再把当前的 ss、tmprsp、rflags、cs、rip,依次压入当前 rsp 指向的栈中。 D、然后会先到达中断处理入口 保护现场 调用到硬件中断分发器函数hal_hwint_allocator 第一个参数为中断编号,在rdi 第二个参数为中断发生时的栈指针,在rsi 然后调用异常处理函数hal_do_hwint E、hal_do_hwint ->调用中断回调函数hal_run_intflthandle 先获取中断异常表intfltdsc_t 然后调用intfltdsc_t.i_serlist 链表上,所有挂载intserdsc_t 结构中的,中断处理的回调函数,让函数自行判断是否处理中断 ->中断处理完毕后调用krlsched_chkneed_pmptsched ->->一路返回,直到中断处理入口,还原现场,继续执行 ->->或者调用krlschedul,继续进行调度,其实就可以返回用户态了 中断进程切换这部分,是硬理解的,不知道能对多少,还请老师指正。

    作者回复: 是正确的

    2021-07-06
    13
  • pedro
    每个进程都有一个内核栈,指向同一个块内核内存区域,共享一份内核代码和内核数据。内核进程一份页表,用户进程两份页表,用户进程多了一份用户空间页表,与其它用户进程互不干扰。

    作者回复: 聪明如你

    2021-07-02
    18
  • 嗣树
    各个进程内核空间都使用同一份页表,通过页表映射到同一物理内存。 咱们的进度还是挺快的,一不留神这周都挺近进程了哈哈哈

    作者回复: 是的

    2021-07-02
    2
  • blentle
    内存管理算是讲完了吗

    编辑回复: 是啊,告一段落了。关键之处课里都讲了,你还可以结合源代码(见Gitee)继续深入学习。

    2021-07-02
    1
  • Slience-0°C
    开源代码项目在哪里?老师

    编辑回复: 请看LMOS朋友助阵写的加餐:https://time.geekbang.org/column/article/429070

    2023-02-16归属地:山东
  • 温雅小公子
    进程是传说中的PCB吗?

    作者回复: PCB是进程的管理数据

    2022-10-10归属地:湖北
  • 严杰
    进程有对应的结构,那线程呢?线程和进程是怎么关联的?

    作者回复: 往下看

    2022-09-29归属地:湖北
  • 内核栈krlstkadr = krlnew(krlstksz); 这个地方,返回的还是物理地址,新建进程的这一部分好像没看到有建立页表的内容

    作者回复: 是虚拟地址

    2022-07-15
    2
  • ifelse
    膜拜各位大神

    作者回复: 哈哈

    2022-02-17
  • O俊
    老师你好,我想问下,线程用到的栈空间在哪个地方?是在进程地址空间中的栈段吗?

    作者回复: 我没支持线程

    2021-09-17
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部