![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
操作系统原理
文章平均质量分 56
记录刷操作系统原理时的笔记
KingOfMyHeart
会好起来的.
展开
-
C++11之线程局部存储 thread_local
我们知道,在Linux系统中,子线程是通过复制来产生的,由于进程是资源分配的最小单位,那么,进程中的线程除了有自身运行时需要的一些栈空间,寄存器等资源,其余资源都是和其他线程共享的,这就会引入一些资源竞争的问题,为应用程序执行带来不确定性。而线程存储指的是一种特殊的内存机制,用于将数据存储在当前线程的私有内存中,这样线程就有自己私有的数据存储空间,不会被其他线程所干扰。实际上,线程局部存储早就出现,由于是一种特殊的内存机制,所以需要操作系统层面的支持。原创 2023-07-23 15:30:55 · 308 阅读 · 0 评论 -
Linux网络发送和接收内核缓冲区大小的设置
网络发送缓冲区和接收缓冲区原创 2022-08-24 21:27:26 · 3203 阅读 · 0 评论 -
linux网络编程之socket,bind,listen,connect,accept
网络编程常用API原创 2022-08-24 21:05:10 · 383 阅读 · 0 评论 -
用户级线程和内核级线程
用户级线程和内核级线程原创 2022-06-27 22:38:39 · 601 阅读 · 0 评论 -
Linux系统线程创建的过程
Linux系统线程创建的流程原创 2022-06-26 23:06:37 · 1365 阅读 · 0 评论 -
Linux中进程的创建过程
Linux系统的产生原创 2022-06-26 21:57:56 · 1568 阅读 · 0 评论 -
0号进程,1号进程,2号进程
是一个内核进程,是所有进程的祖先,也叫做swapper进程。主要作用:执行start_kernel()函数,初始化内核需要的所有数据结构,激活中断,创建1号内核进程(init进程)。只有当没有可运行的进程的时候,才会运行0号进程,0号进程不是一个实实在在可见的进程,它是单用户,单任务的系统启动代码由0号进程创建的1号进程,pid=1,1号进程共享0号进程的所有的数据结构。1号进程一开始是内核进程,先执行init()函数完成内核初始化,然后调用exec()装入可执行程序init(),这样init就变成可原创 2022-06-26 14:58:45 · 2279 阅读 · 0 评论 -
CPU计算和磁盘IO重叠运行提升系统性能(磁盘,网络IO基本过程)
应用程序从磁盘中读取数据的过程:调用read()系列函数,产生系统调用,陷入内核态;CPU设置DMA,包括数据源地址,数据目的地址,数据长度;向磁盘设备控制器发送指令,要求磁盘控制器将目标数据搬运到内存中;磁盘控制器将数据存放到指定的自己的缓冲区,达到一定条件后,将控制器中的数据拷贝到内存中(此时是内核态的内存空间,该过程是DMA的过程,是两个高速存储介质之间的数据搬运);向DMA确认成功,DMA控制器产生一个中断给CPU,中断服务程序返回用户态,继续执行中断时的下一条指令;将内核空间内存中数原创 2022-04-04 20:32:11 · 900 阅读 · 0 评论 -
操作系统如何与外部设备交互
计算机硬件系统架构:实际上,IO总线又可以分为常规IO总线和外围IO总线,常规IO总线是离CPU比较近的总线,即主要用于对时延要求高的设备,比如说显示器;外围总线相反。设备控制器:磁盘有磁盘控制器,打印机有打印机控制器,显卡有显卡控制器,键盘鼠标也有自己的控制器…CPU是不会直接去和这些设备打交道的,对于这些各种各样的外部设备都是由设备控制器去进行控制的拿打印机的设备控制器来举例子,打印机设备控制器主要分为两大部分,寄存器部分和接口控制电路。其中寄存器分为命令寄存器,数据寄存器,状态寄存器原创 2022-04-04 15:49:02 · 3085 阅读 · 0 评论 -
c++面试题:实现一个生产者消费者队列
#include <thread>#include <mutex>#include <condition_variable>#include <queue>#include <iostream>class Queue{public: void Put(int val) { std::unique_lock<std::mutex> lck(mtx_); //队列不为空,通知原创 2021-06-20 17:00:00 · 1031 阅读 · 1 评论 -
IO的阻塞,非阻塞,同步以及异步详解
IO的第一个阶段,数据(指TCP缓冲区数据)的准备状态:阻塞与非阻塞阻塞Linux上,当我们创建或者申请一个文件描述符时,默认时阻塞的举个例子,我们进行网络编程时,调用accept()获取一个连接的文件描述符,然后我们去读写该文件描述符与客户端进行数据的交互:int n = recv(connfd, buf, len, flags);当内核缓冲区的数据没有准备好时,即connfd上没有数据,当前调用该函数的接口的线程将会阻塞,会被操作系统调度程序挂起非阻塞我们可以调用fcntl()相关的方法原创 2021-06-15 21:55:03 · 515 阅读 · 2 评论 -
OS内存管理之页面置换
前面讲到,我们需要将一些页面加载到内存,此时刚好内存上没有可用的物理内存编号,这个时候就需要将一些页面置换到磁盘让出位置。置换的基本策略:置换最近不可能访问的页根据局部性原理,基于过去的行为来预测将来的行为。策略设计太简单,实行起来可能会很低效,如果过于精密和复杂,软硬件开销也会更大,一般需要折中。页框锁定:一些页框是绝对不允许被置换出去的,否则会出错或者影响效率,如:操作系统核心代码关键数据结构正在进行IO操作缓冲区等我们需要将这些页面锁定,不让操作系统对这些页面进行置换或者延迟进原创 2021-05-06 23:13:15 · 143 阅读 · 0 评论 -
基本内存管理方案2---一个进程进入内存中若干不连续的区域(页式,段式,段页式)
页式设计思想:将用户进程地址空间划分为大小相等的页、页面(一般为4K,也有4M的),并从0开始编号将物理内存地址空间划分为大小相等的区域,称为页框,也从0开始编号,也叫做物理页面,页帧,内存块以页为单位进行分配,按照进程所需要的页数来分配,进程地址空间上相邻的页,映射到物理内存上,页不一定相邻。**逻辑地址:**页号(20,页面的编号) + 页内地址(也叫页内偏移,12位)页表:记录了逻辑空间某页面对应在物理地址空间上是哪一页页表项:页表的每一行称为页表项,记录逻辑页号和物理页号的对应关系原创 2021-05-06 22:37:22 · 317 阅读 · 0 评论 -
OS内存管理之虚拟存储技术
概念:当进程运行时,先将其一部分数据和代码装入内存,另外一部分暂留在磁盘,当要执行的指令或者访问的数据不在内存时,由操作系统自动完成将它们从磁盘上调入内存中运行。注意:与交换技术不同,交换技术是将某一个进程换入换出,这里虚拟存储技术换入换出的粒度更加小了。虚拟地址空间:给进程分配的虚拟内存虚拟地址:虚拟内存上数据或者指令的地址,该位置可以被访问,仿佛就是内存的一部分。虚拟内存在哪里:把内存与磁盘有机的进行结合起来使用,从而得到一个容量很大的"内存",即虚拟内存虚拟内存是对内存的抽象,建立在金原创 2021-05-06 22:33:56 · 265 阅读 · 0 评论 -
OS内存管理之Page fault
可能产生异常的情况:需要的访问虚拟页面没有调入内存 — 缺页异常页面访问违反权限错误的访问地址…缺页异常处理主要过程:产生异常操作系统调用异常处理程序获取磁盘地址启动磁盘将该页调入内存:内存有空闲页框,分配,然后直接调入该页面;内存没有空闲页框,将内存中的某个不常用的页框置换出去(需要看具体的页面置换算法),检查该置换页面是否被修改过,如果修改过需要写入磁盘如果没有修改,直接调换出去,将我们需要加载的页面调进内存。...原创 2021-05-06 22:26:54 · 169 阅读 · 0 评论 -
OS内存管理之快表(TLB)的引入
在前面的文章中,讲到操作系统的多级页表映射:多级页表文章背景我们知道,要从虚拟地址转换成一个物理地址,需要访问多次内存查页表,比如2级页表,需要访问2次内存,4级页表,查询需要访问4次内存,这也是一笔不小的开销,这样会让CPU真正执行指令的时间缩短,导致CPU的超高速度优势利用不充分。快表应运而生原理:程序访问的局部性原理,对于一些指令和数据访问,在一段时间内总是高度的频繁本质:Translation Look-aside Buffers实际上就是一个缓冲区,实际上是CPU的高速缓存,可以缓解原创 2021-05-06 22:15:27 · 707 阅读 · 0 评论 -
OS内存管理之页表,页表项以及页目录
页表由多个页表项组成,即页表中每一行的就是一个页表项。页表项中记录的信息:页框号:记录虚页面对应的具体哪个物理页面有效位:标识该页表项对应的虚页面有没有读进内存,否则在磁盘访问位:引用位,标识该页面有没有被访问过修改位:此页面在内存中有没有被修改过,如果被修改过,将来是要被持久化到磁盘上的,该标志位就是这个目的保护位:标识该页面的读写等权限页表项一般是由硬件设计的,因为地址转换时大多数是由硬件完成的。引出页目录:对于32位虚拟地址空间,假设页面大小为4K,页表项大小为4字节:一个进程原创 2021-05-06 21:47:27 · 4683 阅读 · 0 评论 -
OS内存管理之交换技术
产生背景:进程的地址空间大于物理地址空间,即在较小的内存空间运行较大的进程。内存"扩充"技术:1.内存紧缩技术(可变分区)可变分区概述2.覆盖技术:根据程序的逻辑来选择,一些段永远不会同时出现在内存中,假设有段A和段B,他俩永远不会同时加载到内存上运行,那么A和B就可共享某一段物理内存,进行交替的使用物理内存。这就需要程序员显式的声明覆盖结构,比较老的技术了,适用于早期的某些操作系统。3.交换技术:虚拟内存的初步设计,当内存空间紧张时,系统将一些进程暂时移动到外存,把外存中某些进程换进内原创 2021-05-06 07:48:58 · 687 阅读 · 0 评论 -
基本内存管理方案1---整个进程进入内存的一片连续的区域
单一连续区一段时间内,只有一个进程在内存内优点:简单缺点:内存利用率低固定分区把内存空间先分割成若干区域,称作为分区。每个分区的大小可以相同,也可以不同一旦确定,分区大小固定不能变了每个分区装一个且只能装一个进程进程装载时,根据自身所需空间大小,向操作系统进行申请,然后去相应合适分区进行排队。可变分区根据进程的需要,把内存空闲空间分割出一个分区,分配给该进程,剩余的部分成为新的空闲分区运行一段时间后,可能造成下列布局:缺点:造成大量的内存碎片(外碎片)解决方案:碎片紧缩原创 2021-05-05 21:38:05 · 208 阅读 · 0 评论 -
Linux伙伴系统内存分配原理概述
简介:Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 在内核初始化完成之后, 内存管理的责任就由伙伴系统来承担.,该算法由Knowlton设计, 后来Knuth又进行了更深刻的描述.核心思想:将内存按2的幂进行划分,组成若干空闲链表;查找该链表找到能满足进程需求的最佳匹配块。算法基本步骤:将整个可用的内存空间看做一个整体,大小为: 2^u(2的u次方)假设现在一个进程申请的空间为s:如果满足2^(u-1) < s <= 2^u,那么就将这整块内存分配给该进程否则,就将这原创 2021-05-05 19:19:26 · 985 阅读 · 1 评论 -
复习补充一点系统调用实例
内核中的数据不能随意调用,不能随意jmp,毕竟操作系统是帮我们管理资源的,要不然我们还要操作系统做甚。//用户态int main(){ open(/* ..... */); //库函数 return 0;}----------------------------------------//内核态sys_open(/* ...... */){ //do something}如何做到不让用户随意访问内核数据或函数:依赖硬件设计主要原因是将内存大概分割为用户态和内核态。CPL DPL原创 2021-04-26 21:49:16 · 573 阅读 · 0 评论 -
死锁的一些概念和银行家算法
死锁定义:举个例子来阐述死锁,假设当前系统中由两个进程A和B,他们的运行都依赖资源M和N,此时呢,进程A持有了资源N,进程B持有了资源M,进程A在等待资源M,进程B在等待资源N,两个谁也不释放资源,都在等待对方释放,然后两个进程都无法继续向下推进了,这就是死锁。死锁的成因:资源互斥使用,这些资源都是互斥的,不能同时被使用;不能抢占,资源只能由进程主动的去退让;请求和保持状态同时进行,也就是既持有资源,又去请求其他资源;循环等待死锁的处理:预防:破坏死锁出现的条件:1.一次性申请所有原创 2021-04-24 23:33:50 · 524 阅读 · 1 评论 -
互斥锁的实现
一个朋友面试被问到了锁是如何实现的,没答上来,没记错的话这应该是一个操作系统的概念。下面简单叙述一下互斥锁的实现:使用过信号量来进行同步的朋友都知道,信号量都是配合互斥锁来进行的,是因为信号量的p和v操作过程不是原子的,会导致程序出现意想不到的事情。所以我们就引入了锁来保证这个过程不出问题,但是互斥锁本身也是一个数值,系统根据互斥锁的值来决定是不是继续向下执行,那么为什么锁自身的修改就能保证原子性呢:这是依赖于硬件,硬件原子指令法://读者对CAS有印象吗bool TestAndSet(bool原创 2021-04-24 21:57:47 · 2308 阅读 · 3 评论 -
shell命令执行原理
大概原理:int main(){ while(1){ scanf("%s",cmd); if(!fork()){ //如果是子进程,就执行cmd。不和父进程执行一样的指令 exec(cmd); } wait(); }}原创 2021-04-24 19:51:21 · 178 阅读 · 0 评论 -
对实时操作系统是不是有一些误解?
感觉一些人对实时操作系统有误解,以为实时操作系统中的TASK总是能立刻马上就执行的,实际不然,大多数的操作系统相关书籍对此概念都有 描述:实时操作系统是指所有任务都在规定时间内完成的操作系统,也就是必须,满足时序可预测性.实时系统不是反应很快的系统,而是反应具有时序可预测性的系统.不过,往往在现实开发工作中,实时操作系统一般反应都是很灵敏的,这只是实时系统的一个结果,而不是定义.实时系统最重要的部分是进程或者工作的调度.只有精密,合理和及时的进程调度才能保证响应时间,同样,资源也是,需要保证进程或者任务原创 2021-03-31 11:39:49 · 155 阅读 · 1 评论 -
系统调用原理与用户态以及内核态相互切换过程,以linux系统为主
系统调用作用和意义:是沟通用户与内核之间沟通的桥梁。我们知道我们计算机几乎所有的硬件等资源都由我们的操作系统管理,不论是我们还是我们自己编写的软件再或者用户的应用软件对计算机硬件或者其他资源进行操作时 都需要操作系统的“同意”,这些资源由操作系统给我们统一保管和分配。而操作系统给我们预留的这些接口就是系统调用。linux下我们经常使用到的系统调用:1.直接使用系统调用:open w...原创 2019-04-14 11:09:03 · 4671 阅读 · 2 评论 -
硬件中断和软中断的区别
中断中断指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。即在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个新的情况的过程就叫做中断。硬件中断硬件中断是一个异步信号, 表明需要注意, 或需要改变在执行一个同步事件.硬件中断是由与系统相连的外设(比如网卡 硬盘 键盘等)自动产生的. 每个设备或设备集都有他自己的IRQ(中断请求), 基于IRQ,CPU可以将相应的请求分发到相应的硬件驱动上(注: 硬件驱动通常是内核中转载 2020-08-14 20:21:07 · 795 阅读 · 0 评论 -
操作系统中中断、异常以及系统调用
1. 中断:源于外设来源于格式各样的**硬件设备(注意是来自于的硬件设备的)**产生事件,常见的有以下:系统对于用户敲击键盘的响应;系统对于用户移动鼠标的响应;网卡收到来自网络的数据时系统给予响应(epoll的实现依赖于此中断);磁盘中断、显卡、声卡等事件的响应。2. 异常:OS被动处理意想不到的事件,来源于非法的指令、恶意程序或者合法程序执行到了不可预期的指令等,常见异常如下:运算过程中执行了除零操作;进程占用内存资源过高,如OOM;程序中访问了不该访问的地址空间,如其他进程的地原创 2020-08-14 17:39:11 · 552 阅读 · 0 评论 -
操作系统是如何启动的呢
1. 计算机基本组成:冯诺依曼体系结构冯诺依曼结构基本组成包括五部分:逻辑运算器控制器输入设备输出设备内存2. 操作系统的启动过程:2.1 BIOS:Basic Input Output System 基本输入输出处理系统BIOS是我们计算机启动加载到内存上的第一个小程序,也叫固件,即随着机器的上电和掉电而运行和停止;主要作用:进行自检,检查各种各样的设备是否可以正常运行(如显卡驱动、键盘、鼠标、磁盘等);将一个特殊的小程序Bootloader加载到内存中运行。2.2 B原创 2020-08-14 17:11:14 · 1072 阅读 · 0 评论