操作系统常见问题
GPU和CPU区别为什么挖矿、大模型都用GPUCPU相当于全能的计算机大脑能处理很多复杂的任务它的特点就是核心数比较少但是功能很强大GPU一开始是为了图像渲染出现的比较适合固定且重复的任务它能并行的去处理内部有很多的小核心对于挖矿和大模型训练都是需要很多重复的计算操作所以使用GPU会比较的适合IO多路复用和多线程有什么区别IO多路复用和多线程是两种技术IO多路复用是为了提高IO操作的效率和利用率适合IO密集型多线程是为了提高CPU计算的利用率适合CPU密集型IO多路复用在传统的IO模型中当进行IO请求的时候如果IO操作比较久那么现在就会阻塞住等待IO响应这个过程没干其它事情相当于资源被浪费了而IO多路复用就是使用一个线程专门来监视多个IO请求当使用select、poll或epoll等系统调用时等到他们有数据返回才进行处理这个过程业务线程可以去干其它事情不用被阻塞住IO多路复用主要是用来优化IO请求的适用于IO密集型对CPU的计算没什么影响多线程多线程就是一个应用程序里面可以跑多个线程这些线程独立运行任务搭配上多核的优势可以多个任务同时推进大大的提高CPU的利用率适合CPU密集型如何选择如果应用主要受限于 I/O如 Web 服务器或文件服务IO 多路复用可能更高效。如果应用需要执行大量并行计算或利用多核 CPU那么多线程可能是更好的选择。操作系统的IO模型有哪些一次完整的IO步骤数据准备从硬件 —— page cache 内核态缓冲区数据拷贝page cache —— 用户态区分同步/异步主要看第二步是否需要阻塞等待拷贝完成同步阻塞IOBIO进程调用read的时候会阻塞等待直到数据响应回来一般就是用在传统的Socket调用期间干不了其它事情同步非阻塞NIO进程轮询调用 read没数据就立即返回错误不阻塞。但数据一旦就绪拷贝阶段依然阻塞。特点轮询浪费 CPU实际很少直接用。异步非阻塞AIO执行结果不用当前线程来接收直接注册一个回调方法等待执行结果出来通过回调返回给调用方信号驱动IO就是先注册个信号等到有数据的时候内核会通知然后就过去read可以减少轮询但是数据拷贝的时候实际上还是阻塞IO多路复用先阻塞在 select /poll/epoll 上等数据就绪。就绪后再调用 read 完成拷贝拷贝仍阻塞。本质一个线程管理多个连接提升并发。场景高并发网络编程Netty、Redis、Nginx。负载Load和CPU利用率之间有什么区别CPU利用率是指CPU的忙碌程度是一个百分比值表示在某个时间间隔内CPU处于非空闲状态的时间比例负载是指一段时间内系统等待处理的工作量在 Unix-like 系统中负载平均Load Average通常表示在过去 1 分钟、5 分钟和 15 分钟内运行队列的平均长度。运行队列长度是指在某一时刻处于就绪状态和运行状态的进程数量的和。这个数值包括了正在使用 CPU 的进程和等待 CPU的进程。总的来说CPU利用率关注的是CPU的忙碌程度而负载关注的是系统中等待运行的工作量CPU利用率高代表着CPU正在积极工作如果这个参数太低反而说明CPU大部分时间都是空闲的那可能就说明程序还没有把性能发挥到极致高负载意味着等待CPU的进程很多可能会导致系统的整体响应变慢CPU利用率关注的是资源利用率负载关注的是服务的压力进程线程和协程的区别进程是进行资源分配的基本单位线程是处理器调度和分配的基本单位就比如Java程序每运行一次就是一个进程系统的资源分配就是按照进程为粒度进行分配的然后这个进程启动之后又会创建出很多的线程这些线程能共享JVM的资源并且这些线程都是独立执行的单位可以并发执行协程就是虚拟线程这东西是用户态的操作系统完全感知不到可以由我们去决定它的执行逻辑它之所以出现解决的痛点就是只用多线程因为是OS级别的涉及资源争夺会有CPU算了的浪费如果通过异步回调确实也不会阻塞主线程但是会出现回调地狱也就是可读性大大降低为什么需要线程和协程只有进程不行吗对操作系统来说一个任务就是一个进程你运行一次程序就是创建一个进程线程的出现是为了能在进程内部实现并发并且在同一个进程内线程的上下文切换成本是比较低的但是线程终究还是OS级别的它的调度以及资源抢夺都是不小的开销所以就出现了协程协程就是用户态的调度工具一般用来实现异步的效果对比线程它的成本是比较低的适合IO密集型进程间通信方式有哪些进程间通信就是在不同的进程之间进行数据交换和信息传递主要的实现方式有管道管道其实就是一种半双工的通信方式一个进程往管道写入数据另一个进程从管道获取数据主要是通过pipe系统调用来创建管道一般用在父子进程之间进行通信命名管道与普通管道不同命名管道允许一些不相关的进程通过给定的名称进行通信说白了就是一个假文件不同的进程通过这个文件来进行通信适合没有直接关系的进程进行通信消息队列进程可以将消息写入消息队列然后其它进程可以进行读取消息队列的原理就是通过消息缓冲区说白了就是一块公共内存实现的。共享内存信号量这个主要是用来实现进程之间的同步和互斥的通信方式使用这个来加锁socket这个一般用来网络编程中当然也同样可以用于本地进程之间的通信文件映射进程之间可以通过映射同一块文件这样也能实现资源共享你掌握哪些Linux常用命令系统信息top实时显示系统进程和资源的使用情况可以看哪些进程消耗了资源top - 03:57:24 up 29 min, 1 user, load average: 0.00, 0.02, 0.01这一行的几个参数load average系统负载3 个值分别代表 1 分钟、5 分钟、15 分钟 的平均负载核心判断标准单核 CPU负载阈值≈1.0超过 1.0 说明 CPU 开始排队4 核 CPU负载阈值≈4.0超过 4.0 说明 CPU 资源饱和重点看15 分钟负载持续高于 CPU 核心数说明系统长期 CPU 不足up系统运行时间系统连续运行时长排查是否有重启异常users在线用户数当前登录系统的用户数排查异常登录这部分是整体的这部分是进程单独的主要看这两部分对于线上问题想要排查一般就是先看整体可以看一下负载高不高CPU和内存的使用率大不大任务多不多交换区用的多不多如果没什么问题或者想进一步确认就可以看下面部分按照CPU排序和内存排序看看占比是多少使用top主要就是看一下各个资源的使用情况df -h查看磁盘的使用情况du查看某一个目录的使用磁盘大小情况单位是KBdu . 表示查看当前文件夹date查看和设置日期总结一下top看各个进程对资源的使用情况可以看到内存、cpu、负载、交换区等资源使用情况df -h 和 du 都是看磁盘使用情况但是df能看到剩余多少而du是看使用使用多少date 设置日期系统管理ps查看执行进程ubuntuubuntu:~$ ps 2674 PID TTY STAT TIME COMMAND 2674 tty2 Sl 0:15 /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -background none -noreset -keeptty -verbose 3在线上环境可以用来查看Java程序//查找java进程相当于jps命令但是有的时候线上服务器没办法执行jps可以用以下命令代替 ps aux|grep java //查询java进程并高亮显示Xmx参数部分 ps aux|grep java | grep --color Xmxkill 杀死进程一般有 kill -9 表示立即强制杀死kill -15 表示柔性关闭会给进程留一定的反应时间chmod 更改文件或者目录的权限总结一下ps用来查看某一个进程的具体信息kill用来杀死进程chmod用来更改进程或者文件的权限文件操作ls查看当前文件夹下有哪些文件但是不太详细如果想要更加的详细需要使用 llll更加详细的查看当前文件夹下每个目录和文件的信息cd 更换目录更准确的说是进入某一个目录pwd 显示当前目录路径mkdir创建新目录rmkdir删除空目录如果不是空目录会报错rm 删除文件或目录rm 默认情况下不能删除目录加上 -r 表示递归删除f表示要强制删除cp 拷贝目录或是文件使用方式cp 源文件 目标地址如果是拷贝文件夹的话需要加上 -r 表示递归拷贝mvmv 源文件/目录 目标位置/新名字这里就是把test移动到/tt目录下并重命名为abctouch 创建新文件日志查看vi/vim 用来查看和写入日志的如果文件存在就会直接进入如果不存在就会创建文件进入之后需要按 i 进入编辑模式然后可以开始写入写完之后先按Esc然后 :w 表示写入 :q 表示退出:wq表示保存并退出cat 查看文件内容这个只能看不能改一般是用在比较小的文件上会直接把内容输出在控制台more/lessmore是直接展示全部less可以分页查看less要退出的话需要输入qtail查看文件末尾内容head查看文件开始部分内容grep在文件中查询指定内容如何理解select、poll、epoll这几个都是linux中常见的IO多路复用技术IO多路复用技术就是用来实现一个线程盯着其它的线程谁就绪就处理谁不阻塞Selectselect 最多监听1024个文件描述符fd每次执行都会把所有fd从用户态拷贝到内核态然后内核态会标记出哪些已经就绪调用结束需要将fds拷贝到用户态用户态还需要自己遍历一遍才知道哪些fd就绪pollpoll和select几乎是一样的但是因为poll存储fds是使用链表所以没有1024的限制不过同样会出现fds越多每次扫描时间就越久效率越低epollepoll的思路不同它会开一个专门监视的组件这些想要被监视的fd需要注册到这个组件上每次epoll直接把就绪的fd单独收集之后返回给调用者整个过程只有在注册的时候拷贝一次中间无需拷贝并且返回给调用者的也是真正就绪的fds调用者无需重复遍历epoll是通过epoll_wait来获取就绪的fd那么如果就绪的fd一直没有被消费该如何处理呢有两种处理方式 LT、ET默认情况下是LT也就是只要你不处理下次调用epoll_wait还会一直提醒比较安全重复提醒如果使用ET只要你不及时处理下次调用epoll_wait不会把没处理的fd响应给你也就是只提醒一次不安全epoll 为什么快对比select、poll来说它无需每次调用都将fds在用户态和内核态之间来回拷贝只需要在注册的时候拷贝一次即可并且返回就绪的fd时直接把就绪的返回调用方直接处理就行无需反复遍历什么是CPU利用率怎么算的就是CPU的的非空闲时间占比这个值越高说明你的机器的CPU越繁忙一般可以使用top命令查看cpu利用率什么是IO密集什么是CPU密集IO密集型和CPU密集型其实说的是对资源利用的侧重点不同。IO密集型I/O 操作主要包含从磁盘读取数据、写入数据、网络传输、数据库操作等。I/O 密集型任务的瓶颈在于数据的输入和输出过程而不是计算过程。他的特点如下等待时间长I/O 密集型任务通常涉及到大量的等待时间等待磁盘、网络或其他外部设备的响应。计算量小这些任务通常需要的计算量相对较少大部分时间花费在等待 I/O 操作的完成上。适合多线程由于 I/O 操作是非计算密集型的多个线程可以在等待 I/O 操作完成的同时执行其他任务从而提高整体效率。常见的 I/O 密集型操作主要包括了文件的读写、网络请求、数据库查询等。CPU密集型CPU 密集型任务涉及大量的计算操作而不是 I/O 操作。这些任务的瓶颈在于计算能力和处理器的性能。他的特点是计算量大CPU 密集型任务需要进行大量的计算例如复杂的数学运算、数据处理、图像处理等。等待时间少这些任务通常不会有长时间的等待时间主要消耗 CPU 的计算资源。适合多进程可以利用多核处理器来并行计算提升处理速度。CPU 密集型增加线程数没啥用了因为CPU 已经很忙了再有很多线程也忙不过来了只能加 CPU 才有效果。常见的CPU 密集型主要包括了图像处理、数据的计算、音视频编解码操作等会。什么是Load负载就是运行队列中的平均线程数load average 表示机器一段时间内的平均load。这个值越低越好。负载过高会导致机器无法处理其他请求及操作甚至导致死机。什么是MESI缓存一致性协议首先缓存引入的目的就是因为CPU和内存的速度差太多了为了提升整体的计算能力所以引入了缓存也就是在cpu和内存之间加一层但是也带来了缓存不一致问题因为你一般有多个CPU核心缓存又是每个CPU单独的所以缓存会不一致解决的方式给总线加锁因为CPU和其它部件的同行是通过总线来完成的加锁之后就只有一个CPU能操作这个内存中的变量执行结束解锁的时候其它CPU才去读取这个内存中的数据但是效率很低MESI协议大概就是只要CPU修改的时候发现是全局变量会直接发出信号让其它CPU缓存的这个变量的数据直接无效那么等到他们需要读取整个变量的时候就需要重新从内存中读取MESI有四种状态M(Modified)这行数据有效数据被修改了和内存中的数据不一致数据只存在于本Cache中。E(Exclusive)这行数据有效数据和内存中的数据一致数据只存在于本Cache中。S(Shared)这行数据有效数据和内存中的数据一致数据存在于很多Cache中。I(Invalid)这行数据无效。有了这四种状态之后MESI协议的工作流程如下当一个处理器需要读取一个缓存行时它会首先检查该缓存行的状态。如果状态是Exclusive或Shared则直接从缓存中读取数据。因为这两种状态中数据都是有效的。如果状态是Modified则表明数据被修改了则需要先将修改的数据写回主内存然后再从主内存中读取数据。如果状态是Invalid则需要从主内存中加载数据到缓存并设置状态为Exclusive或Shared。当一个处理器修改了一个缓存行时它会将状态设置为Modified并通知其他处理器或核心该缓存行的状态已被修改从而导致其他处理器中相应缓存行的状态变为Invalid。什么是PageCache他的读写过程是怎么样的有什么优缺点在OS中数据是存储在磁盘的如果每次请求数据都需要到磁盘获取那么效率是非常低的所以用一个pageCache将数据替换从磁盘缓存到这里面避免频繁的和磁盘打交道pageCache其实是内存的一种pageCache中的page就是页是计算机内存管理的基本单位一般是4KB有了pageCache之后文件一次读的流程当一个应用程序请求读取文件时操作系统首先检查page cache是否已经包含了所需的数据。如果数据在cache中称为“命中”则直接从内存中读取数据避免了磁盘I/O操作。如果数据不在cache中称为“未命中”则从磁盘读取数据并将数据写入page cache以便下次读取时能够更快地获取数据。这里面读取到数据大小并不是用多少取多少而是采用预读的方式额外读取一些数据预读的大小一般都是以页为单位的。如果请求读取的数据量小于一页通常4k操作系统通常仍会读取完整的一页。如果应用程序请求的数据量大于一页操作系统可能会一次性读取多个连续的页以减少后续的磁盘I/O操作。一次写操作的流程当向文件中写入数据时然后从文件中读取数据到页缓存并且把新数据写入到页缓存中。对于被修改的页缓存内核会定时把这些页缓存刷新到文件中。当一个应用程序请求写入文件时如果要写入的数据所在的页缓存已经存在那么直接把新数据写入到页缓存即可否则内核首先会申请一个空闲的内存页页缓存。操作系统通常将数据写入page cache中而不是立即写入磁盘。这种方法被称为“延迟写”或“写回缓存”write-back caching。页缓存中的数据会标记为“脏页”dirty pages表示这些数据需要写入磁盘操作系统不会立即将脏页写入磁盘而是会等待合适的时机如系统空闲时或达到一定阈值时将脏页批量写入磁盘。这种方式可以减少磁盘写操作的频率提高整体系统性能。脏页写入缓存的触发条件页缓存的大小达到一定阈值时操作系统会触发写入操作将部分或全部脏页写入磁盘。系统内存压力增大时操作系统也可能会主动将脏页写入磁盘以释放内存空间。文件系统的同步操作如fsync、sync命令会强制将所有脏页写入磁盘以确保数据持久化。操作系统将脏页中的数据写入磁盘也不是一条一条写入的通常是按页或多个页的块进行整体写入。写入完成后这些页会被标记为“干净页”clean pages表示数据已经同步到磁盘。page cache 的优点非常明显也很容易理解提高性能按照页去读取和写入磁盘操作减少了对磁盘的频繁I/O操作提高文件读取和写入的速度。减少磁盘损耗磁盘I/O次数少了还能有助于延长磁盘的使用寿命。然而page cache 也有一些潜在的缺点内存占用缓存数据需要占用内存资源如果系统内存有限可能会影响其他应用程序的性能。数据丢失风险由于数据在写入磁盘前暂时存储在内存中如果系统在数据同步到磁盘前崩溃未写入的数据可能会丢失。什么是操作系统的多级缓存多级缓存的出现就是为了应付CPU和内存之间的速度不匹配问题CPU的速度远远快于内存的读写速度所以就搞了一个中间的缓存整个流程就是当CPU需要用到某一个数据的时候发现这个数据不存在就会将这个数据从内存读取到缓存中等待操作结束再将这个数据刷回内存这个的内存是主内存也就是公共区域的内存但是CPU发展的越来越快一层缓存已经跟不上了慢慢出现了多级缓存当CPU要读取一个数据时首先从一级缓存中查找如果没有找到再从二级缓存中查找如果还是没有就从三级缓存或内存中查找。相当于不断地把热点中的热点抽离出来缓存起来什么是分段和分页分页把虚拟内存和物理内存都划分成一小块的页每块一般是4KB每次要读取数据的时候会把物理内存加载到虚拟内存给进程使用如果要读取的数据没被映射进来会触发缺页中断每块一般是固定大小的并且是线性连续的一般不会出现外部碎片但是可能出现内部碎片虚拟地址和物理地址的映射一般是通过页表来映射的优缺点优点内存利用率高无外部碎片只有少量内部碎片。缺点页无逻辑意义不方便共享与保护地址是一维线性的。分段把内存按照进程要求分成一段一段的每段的长度不是固定的优缺点优点符合程序逻辑便于共享、保护、动态增长。缺点会产生外部碎片需要紧凑 / 交换。对比划分单位分页固定大小的页对程序员透明。分段变长的逻辑段程序员可见。碎片分页内部碎片。分段外部碎片。地址结构分页一维线性地址页号 偏移。分段二维地址段号 段内偏移。目的分页为了高效利用内存实现虚拟内存。分段为了逻辑隔离、共享、保护、动态扩展。共享与保护分页不方便分段非常方便按段共享 / 设权限。现代计算机大部分是先采用分段然后段内再采用分页的思想什么是零拷贝传统的读取数据并发送出去的整个流程read(file, buf); // 读文件到用户缓冲区 write(socket, buf); // 发给网络调用read()从用户态切换到内核态DMA把数据从磁盘拷贝到pageCache内核态缓冲区然后把数据返回给我们程度从内核态切换到用户态CPU把数据从pageCache拷贝到用户缓存这里就是我们的buf数组调用write()从用户态切换到内核态CPU把数据从用户缓冲区拷贝到socket内核态缓冲区然后把数据发送出去DMA把数据从socket拷贝到网卡从内核态切换回用户态DMA就是一个数据搬运工具不过只能做磁盘到内存之间内存到内存只能通过CPU来拷贝整个过程经过了四次数据拷贝cpu拷贝2次DMA拷贝2次四次切换那零拷贝要做的就是减少数据拷贝次数或是CPU参与拷贝的次数传统拷贝只要的痛点来源于需要把数据绕一圈也就是先拷贝到用户态然后才写回内核态这个完全没必要零拷贝的目的就是数据无需拷贝到用户态而是用户程序直接操作内核态MMap直接把pageCache映射到用户程序的虚拟空间中用户程序直接操作pageCache无需专门拷贝到用户态来给程序操作整个流程就变成了先从用户态切换到内核态DMA将数据从磁盘拷贝到pageCache用户程序直接操作pageCache调用write的时候需要CPU将数据从pageCache拷贝到socket然后DMA将数据从socket拷贝到网卡快于发现少了一次CPU数据拷贝但还是需要CPU把数据从pageCache发送到socket好处比传统read/write快缺点需要预先指定映射空间大小不适合做变长的场景Mmap会有脏页自动回写机制一旦脏页数量达到一定比例就会触发回写如果是大量随机写场景可能回写很频繁效率不一定有提高mmap映射需要连续虚拟内存空间但是一般都是有上限不适合做大文件的映射sendfile这个是真正做到了零拷贝但是它的使用场景很局限只是用来发送文件并且全程用户态拿不到这个文件流程DMA把数据从磁盘读取到pageCachecpu把数据从pageCache拷贝到socketDMA把数据从socket拷贝到网卡不过一些硬件支持的话CPU无需拷贝完整数据给socket只需要少量的文件描述符就可以接近于零拷贝Direct I/O这个和mmap差不多不过它是直接跳过pageCache直接从磁盘到用户态内存特点数据不进内核缓存直接读写拷贝次数更少操作系统不帮你缓存、不帮你刷盘应用自己管缓存、自己管落盘什么是全双工和半双工单工只能一方发送另一方接收广播电视半双工两端都可以发送和接收但是一段发送的时候另一端只能接收不能同时发送对讲机全双工两端可以同时发送和接收电话什么是时间片对于CPU来说同一时间只能做一件事但是为了让所有程序看起来像是同时进行提高吞吐量就使用了CPU时间片CPU时间片就是把CPU的使用权分配成一段段使用时间固定的片程序只有拿到时间片才能执行程序什么是用户态、内核态如何切换的内核态就是操作系统的核心资源模式只有这个状态下才能访问需要权限的数据用户态是普通模式只能访问到被授权的数据。这样区分就是为了数据的安全性以及避免数据混乱或丢失实现切换一般就是请求一些需要内核态才能拿到资源比如请求获取磁盘数据之类的同步、异步、阻塞、非阻塞怎么理解同步和异步我的理解就是你调用了之后谁来给你数据如果调用了之后需要你这个线程自己来获取结果就是同步如果有人回调给你就是异步阻塞和非阻塞就是你请求了一个数据之后需要一段时间才能获取到那你是阻塞等待还是先去干别的事情等数据响应回来之后才回来处理为什么按位与运算要比取模运算高效因为取模需要先转化成十进制然后再进行计算而按位与是直接在二进制上就完成计算线程的实现方式有哪些一共三种内核级、用户级、用户内核内核级线程直接由操作系统内核来实现不过我们一般用的不是直接使用内核级线程而是它暴露出来的轻量级进程也就是我们俗称的线程相当于多了一层代理把我们的任务交给他去执行优点线程独立调度单个线程阻塞不影响整个进程可利用多核 CPU。缺点创建 / 切换 / 同步需系统调用用户态内核态切换开销大占用内核资源线程数量有限。用户级线程就是协程OS是感知不到的优点线程切换无需进入内核速度快、开销小不依赖系统可移植性强。缺点一个线程阻塞会导致整个进程阻塞无法利用多核 CPU。混合实现用户线程 LWP原理线程的创建在用户空间完成通过线程库进行但是线程的调度是由内核来完成的。多个用户线程通过多路复用来复用多个内核线程优点结合前两者优势切换高效、可利用多核、不会一阻全阻。正在持续写入的日志如何清理echo file_name 替代 追加直接清空内容