当前课程知识点:Linux 内核分析与应用 >  第3章 进程管理 >  3.2 Linux进程创建 >  Video

返回《Linux 内核分析与应用》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《Linux 内核分析与应用》慕课在线视频列表

Video课程教案、知识点、字幕

大家好 我们今天来讲进程的创建

目前在用户程序的开发中呢

不仅仅涉及到进程还涉及到线程和协程

那么它们到底是如何创建的呢

为什么创建了一个进程或者线程后呢

觉得自己对其没有控制权

这是因为创建这件事情完全由操作系统来控制

你只是发出了一个创建的请求

然后呢整个生孩子这件事情就交给了操作系统

如果你对这个过程不了解 那么一旦程序在运行过程中出现问题

你就可能束手无策了

但是这个过程实际上非常的复杂

那么如何入手呢我们来给予简单介绍

我们知道进程呢是系统资源分配的基本单位

线程是独立运行的基本单位

但是这种说法过于笼统

进程的资源到底有哪些 如何体现

线程为什么是轻量级的运行单位 如何体现

从图中可以看出 进程和线程几乎共享所有的资源

包括代码 数据

进程的空间 打开的文件等等

线程只拥有自己的寄存器和栈

这些概念上的代码段 数据段

进程空间 打开的文件

在内核中是如何来表现的呢

那么我们说task_struct结构具有统一性和多样性

内核如何对待

进程 线程和内核线程

Linux内核坚持平等的原则

对它们一视同仁

也就是内核使用唯一的数据结构task_struct结构呢

来分别表示它们

也使用相同的调度算法对这三者进行调度

尽管表面看起来它们很不一样

但是在内核中呢

最终都通过do_fork分别创建

这样的处理对内核来说简单方便

在同一的基础上又保持各自的特性

这是何如做到的呢

我们站在用户态函数库看过去

创建进程和创建线程呢

调用了不同的函数

分别为fork和pthread_create

而对应的系统调用分别为fork和clone

那么vfork和fork呢

比较类似后面会讲到它们二者之间的差别

所有的系统调用进入内核只有一个入口

进去以后就分道扬镳了各自有自己的服务历程

但分手只是暂时的 归到一处是最终的选择

因此do_fork就成为它们的聚合点

do_fork在内核中是怎样的原型呢

那么我们看这个函数的原型 看起来有一堆的参数

是否有眩晕的感觉呢

在用户态调用fork的时候呢

我们轻松自由 一个参数也不需要传递给它

为什么进入内核后就这么麻烦 在这里呢我们就知道

你的风花雪月到底是谁来帮你担当的

我们先看fork调用do_fork

除了SIGCHLD参数外呢

有三个参数呢是空手而来

有两个参数似乎也没有明确的目标

但作为子进程它完全由自己的个性

根本不想共享父进程的任何资源

而是让父进程把它所有的资源给自己复制一份

父进程就真的给他复制一份吗

老爸没有那么傻 而是假装复制了一下

也就是用一个指针指过去而已

等真正需要的时候呢比如

要写一个页面这时候写时复制技术就登场了

只要父子进程中

不管谁想写一个页面的时候呢这个页面才被复制一份

vfork比fork还狡猾直接传递两个标志过去 第一个标志

它表示什么意思表示儿子优先 老爸等待

于是父进程就去睡觉了 等子进程结束以后才能醒来

第二个标志 儿子干脆与父进程待在一个进程的地址空间中

对 就是父子进程共享内存的地址空间

但是呢父进程的页表除外

vfork看起来很聪明 但是实际上聪明反被聪明误

因为写时复制技术的招数更高

也就是更高效 因此呢

它就没有了生存空间 直接被取代了

Clone它的意思就是克隆 对就是克隆技术

线程就是这么诞生的 怎么clone呢 听起来很神秘

实际上很简单 无非就是传递了一堆参数告诉老爸

你这我要共享你 你那我也要共享

于是老爸就把地址空间 文件系统 打开的文件

信号处理函数等等呢

都被儿子的一句话说过去了

看起来实际上就是四个参数的或

如果我是一个内核线程 我的出生是不是更有优势呢 没错

因为用户空间对我来说根本没有意义

我根本就不知道它的存在

那该调用哪个函数创建呢

早期内核中创建内核线程是通过

kernel_thread而创建的 目前内核中调用

kthread_create创建的

其本质也是向do_fork提供

特定的标志而创建

下面我们来看一下task_struct结构带来的统一性

到底谁给我们thread的诞生呢

带来了方便 说到底还是因为我们站在同一个战壕中

对 也就是说task_strcut结构

由此我们的生命历程就有了诸多的相似

不管是被调度到CPU上去跑

还是分配各种资源到最终的诞生呢

都是调用了相同的函数do_fork

能不能看看do_fork代码流程是什么样子呢

下面呢就是do_fork代码流

首先调用copy_process复制父进程的进程控制块

然后获得子进程的PID

如果设置了暂停的标志呢 则子进程的状态也被置为暂停

否则呢通过唤醒函数

将子进程的状态设置为就绪

并且将子进程加入到就绪队列

如果使用了vfork创建进程则阻塞父进程

下面我们来看一下copy_process做了什么事情

那么copy_process主要用于创建进程控制块

以及子进程执行时所需要的其他的数据结构

该函数的参数与do_fork的参数大致相同

并添加了子进程的PID

copy_process所做的处理必须考虑到各种可能的情况

这些特殊的情况呢 也就是通过clone_flags来具体体现

下面呢我们忽略特殊的情况给出一般的执行过程

这张图是copy_process的代码流程图

我们为什么没有给出具体的代码呢

因为内核版本不同呢

它的代码稍有差异 所以我们这里给出的是流程图

那么copy_process这个函数呢它主要是为了

子进程创建父进程PCB的副本

然后呢对子进程PCB中的各个字段进行初始化

同时呢子进程对父进程的各种资源呢

进行复制或者共享

具体取决于clone_flags所设置的标志

每一种资源的复制

或者共享呢

都通过copy_xyz这样的函数完成的

当然子进程通过这样一个函数呢就获得了自己的PID

父进程通过copy_xyz这样的

函数共享各种资源

比如打开的文件

所在的文件系统 进程的地址空间 信号

命名空间等等

如果进入这些函数去阅读

几乎延伸到内核的各个子系统

因此当你还对这些内容

没有了解的时候 先简单的阅读

当你了解了各个子系统以后呢

再回头阅读相关的内容会发现

一个进程的创建牵一发而动全局

把相关的知识呢都可以串起来了

那些零零散散的知识通过do_fork聚集在一起

知识的活力呢也充分的体现出来了

这里为什么不给具体的源代码呢 因为内核版本不同

代码一直在变化 但是

当你对各个对象之间的关系理清楚以后去阅读的话

这些源码就是一种实现了

下面我们看一下进程的生命周期

前面我们详细的介绍了fork的创建过程

与此相应的还有三个系统调用分别为

exec wait exit三个系统调用

在这里我们对三个系统调用的过程就不详细介绍了

它们之间是如何配合的呢

下面让我们用一些形象的比喻来对进程短暂的一生

做一个小小的总结

随着一句fork呢一个新进程呱呱落地

但这时只是老进程的一个克隆

然后呢随着exec呢

新进程呢脱胎换骨

离家独立开始了独立工作的职业生涯

人有生老病死进程也一样

它可以是自然的死亡

即运行到主函数的最后一个大括弧

从容的离我们而去

也可以是中途退场

退场有两种方式

一种是调用exit函数

一种是在主函数内使用return函数

无论哪一种方式呢它都可以留下留言

放在返回值里保留下来

甚至它还可能被谋杀 被其他进程

通过另外一种方式呢结束它的生命

进程死掉以后呢会留下一个空壳

wait站好最后一班岗 打扫战场

使其最终归于无形 这就是进程完整的一生

Linux 内核分析与应用课程列表:

第1章 概述

-1.1 Linux操作系统概述

--1.1 Linux 操作系统概述

-1.2 Linux内核结构以及内核模块编程

--Video

-1.3 Linux内核源码中的双链表结构

--Video

-1.4 源码分析-内核中的哈希表

--Video

-1.5 动手实践-Linux内核模块的插入和删除

--Video

-第1章 概述--章节测验

-第1章导学--引领你进入Linux内核的大门

第2章 内存寻址

-2.1 内存管理之内存寻址

--Video

-2.2 段机制

--Video

-2.3分页机制

--Video

-2.4 动手实践-把虚拟地址转换成物理地址

--Video

-第2章 内存寻址--章节测验

-第二章导学-从零打造自己的操作系统

第3章 进程管理

-3.1 进程概述

--Video

-3.2 Linux进程创建

--Video

-3.3 Linux进程调度

--Video

-3.4 动手实践-打印进程描述符task_struct中的字段

--Video

-3.5工程实践-基于内核模块的负载监控

--Video

-第3章 进程管理--章节测验

-第三章导学-进程背后琳琅满目的宝贝到哪里挖?

第4章 内存管理

-4.1 Linux内存管理机制

--Video

-4.2 进程用户空间管理机制

--Video

-4.3 物理内存分配与回收机制(上)

--Video

-4.4 物理内存分配与回收机制(下)

--Video

-4.5 动手实践-Linux内存映射基础(上)

--Video

-4.6 动手实践-Linux内存映射实现(中)

--Video

-4.7 动手实践-Linux内存映射测试(下)

--Video

-4.8 初学者对内存管理的常见疑惑

--初学者对内存管理的常见疑惑(一)

--初学者对内存管理的常见疑惑(二)

--初学者对内存管理的常见疑惑(三)

-第4章 内存管理--章节测验

第5章 中断

-5.1 中断机制概述

--Video

-5.2 中断处理机制

--Video

-5.3 中断下半部处理机制

--Video

-5.4 时钟中断机制

--Video

-5.5 动手实践-中断上半部的代码分析及应用

--Video

-5.6 动手实践-中断下半部的代码分析及应用

--Video

-第5章 中断--章节测验

第6章 系统调用

-6.1 Linux中的各种API

--Video

-6.2 系统调用机制

--Video

-6.3 动手实践-添加系统调用(系统调用日志收集系统)

--Video

-第6章 系统调用--章节测验

第7章 内核同步

-7.1 内核同步概述

--Video

-7.2 内核同步机制

--Video

-7.3 动手实践-内核多任务并发实例(上)

--Video

-7.4 动手实践-内核多任务并发实例(下)

--Video

-第7章 内核同步--章节测验

第8章 文件系统

-8.1 虚拟文件系统的引入

--Video

-8.2 虚拟文件系统的主要数据结构

--Video

-8.3 文件系统中的各种缓存

--Video

-8.4 页高速缓存机制以及读写

--Video

-8.5 动手实践-编写一个文件系统(上)

--Video

-8.6 动手实践-编写一个文件系统(中)

--Video

-8.7 动手实践-编写一个文件系统(下)

--Video

-第8章 文件系统--章节测验

第9章 设备驱动

-9.1 设备驱动概述

--Video

-9.2 I/O空间管理

--Video

-9.3 设备驱动模型

--Video

-9.4 字符设备驱动程序简介

--Video

-9.5 块设备驱动程序简介

--Video

-9.6 动手实践-编写字符设备驱动程序

--Video

-9.7工程实践-编写块设备驱动的基础(上)

--Video

-9.8 工程实践-块设备驱动程序分析(中)

--Video

-9.9 工程实践-块设备驱动程序实现(下)

--Video

-第9章 设备驱动--章节测验

致谢与说明

-致谢与说明

--Video

直播视频:从Linux内核学习到自主操作系统研发

-从Linux内核学习到自主操作系统研发

附录:实验代码、课件以及相关素材

-各章实验代码

-《Linux内核分析与应用》课件

-《Linux操作系统原理与应用》教材课堂视频

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。