![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
操作系统学习笔记
文章平均质量分 80
Ch_ty
这个作者很懒,什么都没留下…
展开
-
Linux操作系统学习笔记(二十九)深入理解存储器
一. 前言 本文延续上文介绍CPU的基本思路,继续探索计算机的存储器,包括寄存器、CPU缓存、内存和硬盘,在深入了解存储器的基础上,我们可以写出性能更为优异的代码。二. 存储分级 存储分级的根本原因还是性价比,即性能和价格的权衡。最快的当然是SRAM(Static Random-Access Memory,静态随机存取存储器),但是其密度较低、存储数据有限、价格偏高。而DRAM(Dynamic Random Access Memory,动态随机存取存储器)的芯片,比起 SRAM 来说,它的密度更高原创 2021-01-18 22:01:56 · 390 阅读 · 0 评论 -
Linux操作系统学习笔记(二十八)深入理解CPU
一. 前言 在前面一些文章中多多少少有提到一些CPU的结构以及对应的寄存器等,但是总觉得不够透彻,所以单开一文详细叙述CPU的各种知识,从而加深对操作系统和性能的理解。本文从最基本的加法器和乘法器切入,随后介绍CPU的基本架构和实现原理,接着介绍各个核心模块的实现细节,最后介绍CPU的一些高级黑科技。二. 加法器和乘法器2.1 门电路和半加器 如果从二极管如何形成高低电平说起,那怕是要说完大部分《模拟电路设计》和《数字电路设计》的知识了,有兴趣的同学可以回顾一下自行研究,我们就从各种基本门电路原创 2021-01-18 22:00:53 · 1747 阅读 · 0 评论 -
解密虚拟内存0x400000以下的地方
一. 前言 最近看CSAPP时,对以前没有仔细注意的一处知识盲区产生了兴趣,所以进行了深入研究,并写下此文一记录。二. 问题 二话不说直接上图。下图是CSAPP第七章的虚拟内存分析图。书中提到在X86-64位Linux系统中,代码段总是从地址0x400000处开始,后面是数据段。堆在数据段之后,通过调用malloc向上增长… 但是0X400000以下呢?为什么没有提到呢?翻遍全书,都没有一处提到0至0X400000处的空间是做什么用的。实际运行以下cat /proc/self/maps原创 2020-12-19 00:06:37 · 2769 阅读 · 8 评论 -
Linux操作系统学习笔记(二十七)磁盘I/O性能优化
一. 前言 本文是性能优化系列的最后一篇,将分析磁盘I/O的性能指标、测试方法、常见问题的优化套路等内容。二. I/O性能指标及查询工具 磁盘性能的衡量标准经常用到的包括使用率、饱和度、IOPS、吞吐量以及响应时间等。这五个指标是衡量磁盘性能的基本指标。使用率,是指磁盘处理 I/O 的时间百分比。过高的使用率(比如超过 80%),通常意味着磁盘 I/O 存在性能瓶颈。饱和度,是指磁盘处理 I/O 的繁忙程度。过高的饱和度,意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时,磁盘无法接受原创 2020-12-07 22:03:50 · 892 阅读 · 0 评论 -
Linux操作系统学习笔记(二十六)内存性能优化
一. 前言 本文将分析内存的性能指标、测试方法、压测工具以及内存常见问题的优化套路。二. Buffer和Cache 通过free或者top命令我们可以发现其将内存分为了buffer和cache等部分。Buffer 和 Cache 的设计目的,是为了提升系统的 I/O 性能。它们利用内存,充当起慢速磁盘与快速 CPU 之间的桥梁,可以加速 I/O 的访问速度。通过man free可以查阅到下面的说明buffers Memory used by kernel buffers (Buffers原创 2020-12-07 22:01:56 · 373 阅读 · 1 评论 -
Linux操作系统学习笔记(二十五)CPU性能优化
一. 前言 本文介绍Linux服务器CPU性能评估和优化的基本方法。二. CPU性能查询工具详解2.1 平均负载 平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常原创 2020-11-30 12:54:37 · 1065 阅读 · 0 评论 -
Linux操作系统学习笔记(二十四)网络通信之性能优化
一. 前言 在前面的几篇文章中,我们大致介绍了Linux网络协议栈的基本结构体、收发流程、TCP协议设计原理等,整个网络通信其实是一个很复杂的过程。本文介绍性能测试、性能评估、性能优化等方方面面的基本内容和大致优化思路。二. 总体性能参数和工具 对于服务器来说,首先需要一个大致的轮廓来描述其性能,这些性能参数将整个应用视为黑盒,测试其从外部看上去的性能表现,属于第一步需要掌握的数据。只有先掌握了这些数据后,后续的分析才有意义。带宽:表示链路的最大传输速率,单位通常为 b/s (比特 / 秒)原创 2020-11-30 12:53:33 · 1759 阅读 · 0 评论 -
Linux操作系统学习笔记(二十三)网络通信之收包
一. 简介 本文将分析网络协议栈收包的整个流程,收包和发包是刚好相反的过程。根据顺序我们将依次介绍硬件设备驱动层、数据链路层、网络层、传输层、套接字文件系统的相关发包处理流程,内容较多较复杂,主要掌握整个流程即可。二. 网卡驱动层 网卡作为一个硬件,接收到网络包后靠中断来通知操作系统。但是这里有个问题:网络包的到来往往是很难预期的。网络吞吐量比较大的时候,网络包的到达会十分频繁。这个时候,如果非常频繁地去触发中断,会造成频繁的上下文切换,带来极大的开销。因此硬件处理厂商设计了一种机制,就是当一些原创 2020-11-30 12:52:17 · 855 阅读 · 0 评论 -
Linux操作系统学习笔记(二十一)网络通信之三次握手
一. 前言 三次握手的基本知识在前文中已说明,本文从源码入手来详细分析其实现原理。二. 基本过程和API 一个简单的TCP客户端/服务端模型如下所示,其中Socket()会创建套接字并返回描述符,在前文已经详细分析过。之后bind()会绑定本地的IP/Port二元组用以定位,而connect(), listen(), accept()则是本篇的重点所在,即通过三次握手完成连接的建立。三. 源码分析3.1 bind 首先来看看bind()函数。其API如下所示int bind(int原创 2020-10-24 21:47:00 · 604 阅读 · 0 评论 -
关于sysctl同时修改多项参数的方法
在进行Linux系统优化的时候经常会用到sysctl查看以及调整内核参数,如$ sysctl net.ipv4.tcp_wmemnet.ipv4.tcp_rmem = 4096 87380 2756608 对于这种多参数的情况下,我们需要扩上双引号进行修改,如下所示$ sysctl -w net.ipv4.tcp_wmem="XXXX XXXX XXXX"$ sysctl -p 这样才可以正常生效。...原创 2020-10-10 20:45:47 · 445 阅读 · 0 评论 -
Linux操作系统学习笔记(十九)网络通信之套接字
一. 前言 在前面我们逐一分析了进程间通信的各种方法:信号,管道,共享内存和信号量,本文开始将分析更为复杂也是更为常用的另一套进程间通信:网络通信。网络通信和其他进程间通信最大的区别在于不局限于单机,因此成为了互联网时代的主流选择,无论是分布式、云计算、微服务、容器及自动化运营都离不开网络通信,其重要性可想而知。 经过30多年的发展,网络协议栈已经变得极为复杂,远远不是一两篇文章能够说清楚的东西,所以这里着重剖析我们更为关注的东西:网络编程涉及到的相关协议栈。从本文开始,将分别介绍套接字及其创建、网原创 2020-09-19 12:31:34 · 585 阅读 · 0 评论 -
Linux操作系统学习笔记(十八)进程间通信之共享内存和信号量
一. 前言 本文为进程间通信的最后一篇,介绍共享内存和信号量。之所以将二者一起叙述,是因为二者有着密不可分的关系。共享内存会利用虚拟内存和物理内存的映射关系,让不同进程开辟一块虚拟空间映射到相同的物理内存上,从而实现了两个进程对相同区域的读写,即进程间通信。而信号量则实现了互斥锁,可以为共享内存提供数据一致性的保证,因此二者常结合使用。二. 基础知识 共享内存的使用包括调用shmget()创建共享内存调用shmat()映射共享内存至进程虚拟空间调用shmdt()接触映射关系 信号量原创 2020-09-19 12:30:38 · 1452 阅读 · 0 评论 -
Linux操作系统学习笔记(十七)进程间通信之管道
一. 前言 上文中我们介绍了进程间通信的方法之一:信号,本文将继续介绍另一种进程间通信的方法,即管道。管道是Linux中使用shell经常用到的一个技术,本文将深入剖析管道的实现和运行逻辑。二. 管道简介 在Linux的日常使用中,我们常常会用到管道,如下所示ps -ef | grep 关键字 | awk '{print $2}' | xargs kill -9 这里面的竖线|就是一个管道。它会将前一个命令的输出,作为后一个命令的输入。从管道的这个名称可以看出来,管道是一种单向传输数据的原创 2020-08-30 12:14:51 · 571 阅读 · 0 评论 -
Linux操作系统学习笔记(十六)进程间通信之信号
一. 前言 众所周知,System V IPC进程间通信机制体系中有着多种多样的进程间通信方式,如管道和有名管道,消息队列,信号,共享内存和信号量,套接字。从本文开始我们就逐个剖析进程间通信的机制和底层原理,就从信号开始讲起吧。二. 信号基本知识 信号是进程处理紧急情况所用的一种方式,它没有特别复杂的数据结构,就是用一个代号一样的数字。Linux 提供了几十种信号,分别代表不同的意义。我们可以通过kill -l命令查看信号。# kill -l 1) SIGHUP 2) SIGIN原创 2020-08-30 12:13:57 · 615 阅读 · 0 评论 -
Linux操作系统学习笔记(十五)中断
一. 前言 在前面的文章里,我们多次见到了中断的作用,如任务调度,系统调用从用户态陷入内核,文件系统的读写操作等。本文就Linux的中断机制进行较为全面的剖析。二. 什么是中断 中断通常被定义为改变处理器执行指令的顺序的一个事件,该事件与CPU芯片内外部硬件电路产生的电信号相对应。中断通常分为同步中断和异步中断:同步中断(synchronous):又称异常(exception),在指令执行时由CPU控制单元产生,之所以称之为同步,是因为只有在一条指令终止执行后CPU才会发出中断。异步中断(原创 2020-08-30 12:13:01 · 740 阅读 · 0 评论 -
Linux操作系统学习笔记(十四)块设备
一. 前言 上文我们分析了字符设备,本文接着分析块设备。我们首先分析块设备的基本结构体,然后分析块设备生成、加载的整个过程,最后分析块设备的直接I/O访问和缓存I/O访问。二. 块设备基本结构体 上文中我们分析了字符设备驱动程序的抽象结构体cdev和管理cdev的结构体cdev_map,在块设备中会相对复杂一些,因为涉及到一个概念:伪文件系统bdevfs。在此之下主要有三个结构体:对块设备或设备分区的抽象结构体block_device,对磁盘的通用描述gendisk以及磁盘分区描述hd_struc原创 2020-08-21 22:12:30 · 4013 阅读 · 0 评论 -
Linux操作系统学习笔记(十三)字符设备
一. 前言 上文中我们分析了虚拟文件系统的结构以及常见的文件操作从用户态到虚拟文件系统再到底层实际文件系统的过程。而实际上我们并没有说明实际的文件系统如ext4是如何和磁盘进行交互的,这就是本文和下篇文章的重点:I/O之块设备和字符设备。输入输出设备我们大致可以分为两类:块设备(Block Device)和字符设备(Character Device)。块设备将信息存储在固定大小的块中,每个块都有自己的地址。如硬盘就是常见的块设备。字符设备发送或接收的是字节流,而不用考虑任何块结构,没有办法寻原创 2020-08-17 13:04:56 · 1084 阅读 · 0 评论 -
Linux操作系统学习笔记(十二)虚拟文件系统
一. 前言 基于上文介绍的文件系统的基本结构,本文将继续深入Linux文件系统的精髓所在:虚拟文件系统。操作文件的本质是将磁盘文件数据映射到进程中,上文的文件系统是如何存储文件数据,而从进程如何映射到该文件系统,中间还有一系列的过程,主要包括进程发出文件操作命令,通过系统调用如sys_open、sys_read、sys_write调用相应内核函数在内核中为进程打开的文件和系统文件创建数据结构进行维护通过虚拟文件系统对各种不同的文件系统操作,如I/O设备、管道、进程间通信、网络等进行抽象并统一接口原创 2020-07-31 12:28:12 · 1072 阅读 · 0 评论 -
Linux操作系统学习笔记(十一)文件系统
一. 前言 本节开始将分析Linux的文件系统。Linux一切皆文件的思想可谓众所周知,而其文件系统又是字符设备、块设备、管道、进程间通信、网络等等的必备知识,因此其重要性可想而知。本文将先介绍文件系统基础知识,然后介绍最重要的结构体inode以及构建于其上的一层层的文件系统。二. 文件系统基础知识 一切设计均是为了实现需求,因此我们从文件系统需要的基本功能来看看其该如何设计。首先,一个文件系统需要有以下基本要求文件需要让人易于读写,并避免名字冲突等文件需要易于查找、整理归类操作系统需要原创 2020-07-31 12:27:30 · 478 阅读 · 0 评论 -
Linux操作系统学习笔记(十)内存管理之内存映射
一. 前言 本文为内存部分最后一篇,介绍内存映射。内存映射不仅是物理内存和虚拟内存间的映射,也包括将文件中的内容映射到虚拟内存空间。这个时候,访问内存空间就能够访问到文件里面的数据。而仅有物理内存和虚拟内存的映射,是一种特殊情况。本文首先分析用户态在堆中申请小块内存的brk和申请大块内存的mmap,之后会分析内核态的内存映射机制vmalloc,kmap_atomic,swapper_pg_dir以及内核态缺页异常。二. 用户态内存映射 用户态调用malloc会分配堆内存空间,而实际上则是完成了一原创 2020-07-08 12:49:11 · 646 阅读 · 0 评论 -
Linux操作系统学习笔记(九)内存管理之分页
一. 前言 上文分析了内存再用户态的结构体mm_struct及各个区域映射的vm_area_struct以及32位和64位的内核态结构体,本文将基于这些结构来分析Linux的内存管理系统。内存管理系统包括虚拟内存和物理内存的分页以及虚拟内存和物理内存的映射。本文将介绍分页机制,而映射则在下文中说明。本文首先简单介绍SMP和NUMA系统,然后对物理内存的节点、区域、页结构进行分析,在此基础上剖析伙伴系统和Slub Allocator的实现原理,最后介绍页面交换。二. 内存模型 在计算机的发展历程中原创 2020-07-08 12:48:12 · 650 阅读 · 0 评论 -
Linux操作系统学习笔记(八)任务空间管理
一. 前言 从本文开始,我们进入内存部分的学习。首先会接着前面的任务task_struct讲解任务空间管理结构体mm_struct,并简单介绍物理内存和虚拟内存的相关知识,关于详细的基础知识和概念可以参照CSAPP一书,这里不会做过多的赘述,而是默认在已了解其映射关系的基础上进行的学习。在后文中,会继续介绍物理内存的管理以及用户态和内核态的内存映射。二. 基本概念梳理CPU、缓存、内存、主存的架构是源于越快的设备越贵,因此出于节约(qiong)考虑设计了多层架构,CPU中有了MMU物理内存有限,原创 2020-06-25 17:42:38 · 715 阅读 · 0 评论 -
Linux操作系统学习笔记(七)任务调度
一. 前言 在前文中,我们分析了内核中进程和线程的统一结构体task_struct,并分析进程、线程的创建和派生的过程。在本文中,我们会对任务间调度进行详细剖析,了解其原理和整个执行过程。由此,进程、线程部分的大体框架就算是介绍完了。本节主要分为三个部分:Linux内核中常见的调度策略,调度的基本结构体以及调度发生的整个流程。下面将详细展开说明。二. 调度策略 Linux的调度策略主要分为实时任务和普通任务。实时任务需求尽快返回结果,而普通任务则没有较高的要求。在前文中我们提到了task_str原创 2020-06-13 11:28:38 · 1370 阅读 · 0 评论 -
Linux操作系统学习笔记(六)进程、线程的创建和派生
一. 前言 在前文中,我们分析了内核中进程和线程的统一结构体task_struct,本文将继续分析进程、线程的创建和派生的过程。首先介绍如何将一个程序编辑为执行文件最后成为进程执行,然后会介绍线程的执行,最后会分析如何通过已有的进程、线程实现多进程、多线程。因为进程和线程有诸多相似之处,也有一些不同之处,因此本文会对比进程和线程来加深理解和记忆。二. 进程的创建 以C语言为例,我们在Linux下编写C语言代码,然后通过gcc编译和链接生成可执行文件后直接执行即可完成一个进程的创建和工作。下面将详细原创 2020-06-13 11:26:39 · 1002 阅读 · 0 评论 -
Linux操作系统学习笔记(五)进程的核心——task_truct
一. 前言 在前文中,我们分析了内核启动的整个过程以及系统调用的过程,从本文开始我们会介绍Linux系统各个重要的组成部分。这一切就从进程和线程开始,在 Linux 里面,无论是进程,还是线程,到了内核里面,我们统一都叫任务(Task),由一个统一的结构 task_struct 进行管理。这个结构非常复杂,本文将细细分析task_struct结构。主要分析顺序会按照该架构体中的成员变量和函数的作用进行分类,主要包括:任务ID亲缘关系任务状态任务权限运行统计进程调度信号处理内存管理文件原创 2020-05-31 21:18:27 · 1545 阅读 · 1 评论 -
Linux操作系统学习笔记(四)系统调用
前言 通过前面几篇文章,我们分析了从按下电源键到内核启动、完成初始化的整个过程。在后面的文章中我们将分别深入剖析Linux内核各个重要部分的源码。考虑到后面的部分我们会从用户态的代码开始入手一步一步深入,因此在分析这些之前,我们需要仔细看一看如何实现一个从用户态到内核态再回到用户态的系统调用的全过程,即系统调用的实现。 本文的说明顺序如下首先从一个简单的例子开始分析glibc中对应的调用针对32位和64位中调用的结构不同会分开两部分单独介绍,会介绍整个调用至完成的过程。即用户态->内核原创 2020-05-24 10:36:39 · 1064 阅读 · 0 评论 -
Linux操作系统学习笔记(三)内核初始化
前言 前文分析到Linux内核正式启动,完成了实模式到保护模式的切换,并做好了各种准备工作。下来就要看开始内核初始化工作了,源码位置位于init/main.c中的start_kernel(),源码如附录所示。这包括了一系列重要的初始化工作,本文会介绍其中一部分较为重要的,但是详细的介绍依然会留在后文各个模块的源码学习中单独进行。本文的目的在于承接上文给出一个从内核启动到各个模块开始运转的过程介绍,而不是详细的各部分内容介绍。创建0号进程:INIT_TASK(init_task)异常处理类中断原创 2020-05-17 22:47:56 · 1379 阅读 · 0 评论