趣谈Linux操作系统
刘超
网易杭州研究院云计算技术部首席架构师
立即订阅
19393 人已学习
课程目录
已完结 72 讲
0/4登录后,你可以任选4讲全文学习。
入门准备篇 (3讲)
开篇词 | 为什么要学习Linux操作系统?
免费
01 | 入学测验:你究竟对Linux操作系统了解多少?
02 | 学习路径:爬过这六个陡坡,你就能对Linux了如指掌
核心原理篇:第一部分 Linux操作系统综述 (3讲)
03 | 你可以把Linux内核当成一家软件外包公司的老板
04 | 快速上手几个Linux命令:每家公司都有自己的黑话
05 | 学会几个系统调用:咱们公司能接哪些类型的项目?
核心原理篇:第二部分 系统初始化 (4讲)
06 | x86架构:有了开放的架构,才能打造开放的营商环境
07 | 从BIOS到bootloader:创业伊始,有活儿老板自己上
08 | 内核初始化:生意做大了就得成立公司
09 | 系统调用:公司成立好了就要开始接项目
核心原理篇:第三部分 进程管理 (10讲)
10 | 进程:公司接这么多项目,如何管?
11 | 线程:如何让复杂的项目并行执行?
12 | 进程数据结构(上):项目多了就需要项目管理系统
13 | 进程数据结构(中):项目多了就需要项目管理系统
14 | 进程数据结构(下):项目多了就需要项目管理系统
15 | 调度(上):如何制定项目管理流程?
16 | 调度(中):主动调度是如何发生的?
17 | 调度(下):抢占式调度是如何发生的?
18 | 进程的创建:如何发起一个新项目?
19 | 线程的创建:如何执行一个新子项目?
核心原理篇:第四部分 内存管理 (7讲)
20 | 内存管理(上):为客户保密,规划进程内存空间布局
21 | 内存管理(下):为客户保密,项目组独享会议室封闭开发
22 | 进程空间管理:项目组还可以自行布置会议室
23 | 物理内存管理(上):会议室管理员如何分配会议室?
24 | 物理内存管理(下):会议室管理员如何分配会议室?
25 | 用户态内存映射:如何找到正确的会议室?
26 | 内核态内存映射:如何找到正确的会议室?
核心原理篇:第五部分 文件系统 (4讲)
27 | 文件系统:项目成果要归档,我们就需要档案库
28 | 硬盘文件系统:如何最合理地组织档案库的文档?
29 | 虚拟文件系统:文件多了就需要档案管理系统
30 | 文件缓存:常用文档应该放在触手可得的地方
核心原理篇:第六部分 输入输出系统 (5讲)
31 | 输入与输出:如何建立售前售后生态体系?
32 | 字符设备(上):如何建立直销模式?
33 | 字符设备(下):如何建立直销模式?
34 | 块设备(上):如何建立代理商销售模式?
35 | 块设备(下):如何建立代理商销售模式?
核心原理篇:第七部分 进程间通信 (7讲)
36 | 进程间通信:遇到大项目需要项目组之间的合作才行
37 | 信号(上):项目组A完成了,如何及时通知项目组B?
38 | 信号(下):项目组A完成了,如何及时通知项目组B?
39 | 管道:项目组A完成了,如何交接给项目组B?
40 | IPC(上):不同项目组之间抢资源,如何协调?
41 | IPC(中):不同项目组之间抢资源,如何协调?
42 | IPC(下):不同项目组之间抢资源,如何协调?
核心原理篇:第八部分 网络系统 (7讲)
43 预习 | Socket通信之网络协议基本原理
43 | Socket通信:遇上特大项目,要学会和其他公司合作
44 | Socket内核数据结构:如何成立特大项目合作部?
45 | 发送网络包(上):如何表达我们想让合作伙伴做什么?
46 | 发送网络包(下):如何表达我们想让合作伙伴做什么?
47 | 接收网络包(上):如何搞明白合作伙伴让我们做什么?
48 | 接收网络包(下):如何搞明白合作伙伴让我们做什么?
核心原理篇:第九部分 虚拟化 (7讲)
49 | 虚拟机:如何成立子公司,让公司变集团?
50 | 计算虚拟化之CPU(上):如何复用集团的人力资源?
51 | 计算虚拟化之CPU(下):如何复用集团的人力资源?
52 | 计算虚拟化之内存:如何建立独立的办公室?
53 | 存储虚拟化(上):如何建立自己保管的单独档案库?
54 | 存储虚拟化(下):如何建立自己保管的单独档案库?
55 | 网络虚拟化:如何成立独立的合作部?
核心原理篇:第十部分 容器化 (4讲)
56 | 容器:大公司为保持创新,鼓励内部创业
57 | Namespace技术:内部创业公司应该独立运营
58 | CGroup技术:内部创业公司应该独立核算成本
59 | 数据中心操作系统:上市敲钟
实战串讲篇 (9讲)
60 | 搭建操作系统实验环境(上):授人以鱼不如授人以渔
61 | 搭建操作系统实验环境(下):授人以鱼不如授人以渔
62 | 知识串讲:用一个创业故事串起操作系统原理(一)
63 | 知识串讲:用一个创业故事串起操作系统原理(二)
64 | 知识串讲:用一个创业故事串起操作系统原理(三)
65 | 知识串讲:用一个创业故事串起操作系统原理(四)
66 | 知识串讲:用一个创业故事串起操作系统原理(五)
67 | 期末测试:这些操作系统问题,你真的掌握了吗?
结束语 | 永远别轻视任何技术,也永远别轻视自己
免费
专栏加餐 (2讲)
学习攻略(一):学好操作系统,需要掌握哪些前置知识?
“趣谈Linux操作系统”食用指南
免费
趣谈Linux操作系统
登录|注册

12 | 进程数据结构(上):项目多了就需要项目管理系统

刘超 2019-04-22
前面两节,我们讲了如何使用系统调用,创建进程和线程。你是不是觉得进程和线程管理,还挺复杂的呢?如此复杂的体系,在内核里面应该如何管理呢?
有的进程只有一个线程,有的进程有多个线程,它们都需要由内核分配 CPU 来干活。可是 CPU 总共就这么几个,应该怎么管理,怎么调度呢?你是老板,这个事儿得你来操心。
首先,我们得明确,公司的项目售前售后人员,接来了这么多的项目,这是个好事儿。这些项目都通过办事大厅立了项的,有的需要整个项目组一起开发,有的是一个项目组分成多个小组并行开发。无论哪种模式,到你这个老板这里,都需要有一个项目管理体系,进行统一排期、统一管理和统一协调。这样,你才能对公司的业务了如指掌。
那具体应该怎么做呢?还记得咱们平时开发的时候,用的项目管理软件 Jira 吧?它的办法对我们来讲,就很有参考意义。
我们这么来看,其实,无论是一个大的项目组一起完成一个大的功能(单体应用模式),还是把一个大的功能拆成小的功能并行开发(微服务模式),这些都是开发组根据客户的需求来定的,项目经理没办法决定,但是从项目经理的角度来看,这些都是任务,需要同样关注进度、协调资源等等。
同样在 Linux 里面,无论是进程,还是线程,到了内核里面,我们统一都叫任务(Task),由一个统一的结构 task_struct 进行管理。这个结构非常复杂,但你也不用怕,我们慢慢来解析。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《趣谈Linux操作系统》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(35)

  • why
    - 内核中进程, 线程统一为任务, 由 taks_struct 表示
    - 通过链表串起 task_struct
    - task_struct 中包含: 任务ID; 任务状态; 信号处理相关字段; 调度相关字段; 亲缘关系; 权限相关; 运行统计; 内存管理; 文件与文件系统; 内核栈;
    - 任务 ID; 包含 pid, tgid 和 \*group_leader
        - pid(process id, 线程的id); tgid(thread group id, 所属进程[主线程]的id); group_leader 指向 tgid 的结构体
        - 通过对比 pid 和 tgid 可判断是进程还是线程
    - 信号处理, 包含阻塞暂不处理; 等待处理; 正在处理的信号
        - 信号处理函数默认使用用户态的函数栈, 也可以开辟新的栈专门用于信号处理, 由 sas_ss_xxx 指定
        - 通过 pending/shared_pending 区分进程和线程的信号
    - 任务状态; 包含 state; exit_state; flags
        - 准备运行状态 TASK_RUNNING
        - 睡眠状态:可中断; 不可中断; 可杀
            - 可中断 TASK_INTERRUPTIBLE, 收到信号要被唤醒
            - 不可中断 TASK_UNINTERRUPTIBLE, 收到信号不会被唤醒, 不能被kill, 只能重启
            - 可杀 TASK_KILLABLE, 可以响应致命信号, 由不可中断与 TASK_WAKEKILL 组合
        - 停止状态 TASK_STOPPED, 由信号 SIGSTOP, SIGTTIN, SIGTSTP 与 SIGTTOU 触发进入
        - 调试跟踪 TASK_TRACED, 被 debugger 等进程监视时进入
        - 结束状态(包含 exit_state)
            - EXIT_ZOMBIE, 父进程还没有 wait()
            - EXIT_DEAD, 最终状态
        - flags, 例如 PF_VCPU 表示运行在虚拟 CPU 上; PF_FORKNOEXEC \_do_fork 函数里设置, exec 函数中清除
    - 进程调度; 包含 是否在运行队列; 优先级; 调度策略; 可以使用那些 CPU 等信息.
    2019-04-22
    28
  • 唐稳
    介绍的很详细,赞一个。
    有个问题一直纠结,信号处理函数到底是在哪个线程中运行的?

    作者回复: 不在任何一个线程中,后面会详细解析信号处理的过程

    2019-05-01
    1
    6
  • Egos
    看文章理解的task_struct 是Thread 的一个链表?

    作者回复: 进程和线程在一起的链表

    2019-04-22
    1
    5
  • 积微致知
    老师好,有个疑惑所有的task_struct为什么用链表串联起来而不是用数组?
    数组在物理空间上必须要连续,而链表物理空间上可以不连续。
    2019-04-23
    1
    4
  • 中翅Lzc
    如果进程创建了其他多个线程,那么tpid就是主线程id,pid就是其他线程id了,两者肯定不相等啊

    作者回复: 对的

    2019-04-22
    3
  • 第十人
    tgid和threadleader都是进程的主线程,那这两个参数不就重复了么?有其他的含义么?

    作者回复: 一个是id,一个是指针,只知道ID,不得一个个找么

    2019-04-22
    3
  • ECHOLOG
    举一反三一下,因为线程和进程都是task_struct表示的,所以有僵尸进程,那就有僵尸线程

    作者回复: 对的pthread_join

    2019-08-19
    2
  • 勤劳的小胖子-libo
    应该是一个值,一个是指针用于快速访问吧。。

    作者回复: 对

    2019-05-11
    1
  • 勤劳的小胖子-libo
    任何一个进程,如果只有主线程,那 pid 是自己,tgid 是自己,group_leader 指向的还是自己。

    但是有多个线程就不一样了,pid是这个子线程,tgid和group_leader都是指向主线程。

    好奇,tgid与group_leader不就相同作用吗?在上面的二种情况下,为什么需要二个相同功能的域?

    作者回复: 一个是id,一个是地址,有地址就能直接找到了

    2019-05-11
    1
  • 一笔一画
    老师,请教一下,之前看书上说用户进程和内核线程是多对多的模型?这个怎么理解,我们常用的发行版又是什么样的模型?

    作者回复: 操作系统的理论是有多种模型的,多对一,一对一,多对多,Linux是一对一。

    2019-04-23
    1
  • Dracula
    老师好,有个疑惑所有的task_struct为什么用链表串联起来而不是用数组

    作者回复: 很多插入和删除

    2019-04-22
    1
  • jueyoq
    1. 进程的标示 pid/tgid/group_leader 是用来方便区分任务是线程还是进程,而区分二者的需求来自远多维度的展示任务与向进程或者线程发送信号
    2. 进程的状态设定同样来源于两个需求, 监控统计任务的执行过程,以及调度任务。而任务的状态来自于处理任务的一般思路,创建一个任务,准备处理任务,处理任务,任务被搁置,任务被解决,同时为了可以更加细粒度的监控进程引入debug的状态。
    2019-10-24
  • sinfool
    ‘通过pid==tgid来判断是线程还是进程'这句话实在是不懂。如果是单线程,pid==tgid,没有问题;如果是多线程,当前线程如果是主线程,pid不是也等于tgid么?这怎么说?
    2019-10-09
  • kdb_reboot
    再次阅读,本章可以参考lkd(process management) 一起看
    2019-09-24
  • 计算机班陈公子
    老师有个问题就是在进程状态变成zombie后,他在等父进程调用wait() 来回收自己的空间是么?所以在回收完他的空间后他就彻底进入了EXIT_DEAD状态是么?可是为什么top命令下的S 栏里面没有dead这个状态,而只有R,S,D,T,Z这五个?
    另外在进程收到SIGTERM或者SIGKILL这样terminate类的信号时,进程也是进入了EXIT_DEAD状态么?
    2019-09-11
  • jijun gao
    打个卡:task_struct结构中,pid是线程id。从pid的名字来看,是process id, 即进程id. 此处,可以理解为,线程是轻量级的进程。tgid是线程所属进程的主线程id
    2019-09-08
  • 天王
    进程的数据结构1 进程和线程,1.1有的进程只有一个线程,有的有1.2 多个线程,都需要内核分配CPU来干活。在内核里进程和线程统称任务,数据结构都是task_struct。1.3 linux的任务管理都做什么用,1.31首先要有个任务链表,struct list_head,把所有任务串起来1.32 都有一个任务id,pid全称processid,tgid全称task group id,之所以要有pid和tgid,一是任务展示,二是给任务发指令 是给进程发还是某一个线程发 有了pid和tgid,用两者是否相等,就能知道是线程还是进程2 信号处理 task_struct 里面也有涉及信号处理的字段 sigset_t blocked定义了信号阻塞暂不处理,sigpending pending 哪些信号尚等待处理,哪些信号正在通过sighand函数进行处理,信号处理函数默认使用用户态的函数栈 3 进程调度 优先级,调度类sched_class,调度策略,调度实体sched_entity,4任务状态 在task_struct类中,state属性 TASK_RUNNIng 表示处于即将运行的状态,时间片切换到这个进程,就会立刻运行,睡眠状态有3种,Task_interruptible,可中断的睡眠状态,浅睡眠状态,信号来的时候被唤醒,处理函数可以自己定义,task_uninterruputible,不可唤醒的睡眠状态,死等io操作,task_killabe收到致命信号可以被唤醒,task_track表示进程被其他进程监视,进程执行被调试进程所终止,一个进程结束要先进入exit_zomble状态,如果他的父进程还没有使用wait等系统调用获取终止信息,该进程就成了僵尸进程。exit_dead是进程的最终状态。调度还有一些标志以PF开头,pf_exiting表示正在退出,pf_vcpu表示运行在虚拟cpu上。
    2019-08-14
  • ...
    从定义的数值很容易看出来,flags 是通过 bitset 的方式设置的也就是说,当前是什么状态,哪一位就置一。 结合上下文发现是不是笔误,flags应该改成state

    作者回复: 你是对的,是state

    2019-08-12
  • kdb_reboot
    实在是不理解为什么那么多人问"为什么用链表而不是数组..."
    补充: 本节讲的内容在sched.h里面, 思考题完全可以搜一下这个"task->state"

    作者回复: 赞

    2019-07-22
  • garlic
    目前理解的, 任务状态主要在TASK_RUNNING, TASK_INTERRUPTIBLE, TASK_UNINTERRUPTIBLE, TASK_KILLABLE间互相转换, 其他一些状态TASK_PARKED,TASK_NEW为了解决相关问题引入的。 学习笔记https://garlicspace.com/2019/06/29/linux任务状态定义/

    作者回复: 赞

    2019-06-29
收起评论
35
返回
顶部