操作系统
发布日期:2021-10-12 21:31:52 浏览次数:3 分类:技术文章

本文共 4883 字,大约阅读时间需要 16 分钟。

进程,线程,协程的区别?

   进程是资源分配的最小单元,它有自己独立的地址空间和独立的堆,操作系统以进程为单位来分配系统资源,比如cpu时间片和内存空间

   线程有时候被称为轻量级进程,是操作系统调度(cpu调度)执行的最小单位

   区别:

                1.线程是调度和分配的基本单位,进程作为拥有资源的基本单位

                 2.进程之间可以并发执行,同一个进程内的多个线程之间也能够并发执行

                3.进程是拥有资源的一个独立单位,线程不拥有系统资源,但是可以访问进程的资源

                4.进程的创建和销毁的开销更大,进程有独立的地址空间,所以一个进程崩溃后,并不会对其他进程产生影响,而一个线程崩溃后所有线程都会崩溃。所以多进程比多线程更健壮,但是进程切换开销更大,而线程只需要切换线程上下文就行

     协程:是一种比线程更加轻量级的存在,不是被操作系统内核管理的,而是完全在用户态执行。这样带来的好处是性能得到了很大的提升,不会像切换线程那样消耗资源

    优点:执行效率高。是子程序切换而不是线程切换,由程序自身控制,所以没有线程切换的开销,线程越多,协程的性能优势越明显

              协程不需要多线程的锁机制,因为只有一个线程,所以不存在同时写变量冲突,在协程中控制共享资源不需要加锁,只需要判断状态就好了

 

线程调度方式?

     1.抢占式调度:一个线程在执行自己的任务时,虽然任务还没有执行完成,但是cpu迫使它暂停,让其他线程占有cpu的使用权

     2.协作式调度:一个线程在执行自己的任务时,不允许被中途打断,一定要等当前线程将任务执行完成后才会释放对cpu的占用,然后其他线程才可以抢占该cpu

      java使用的就是抢占式调度

 

IO模型?

   阻塞IO:进程调用读取指令后阻塞直到数据复制到内存完毕

   非阻塞IO:进程调用读取指令后进程可以处理其他任务后再查看数据是否准备完毕

   多路复用IO:改进的阻塞IO,可以处理多个连接,多路复用有select,poll,epoll

  信号驱动IO

   AIO:进程调用读取指令后内核负责处理数据从IO设备直至复制至内存后再回调进程函数

 

 

线程同步的方式?

互斥量  synchronized/Lock    

信号量 semphare

事件(信号) wait/notify

 

进程有哪几种状态?

就绪状态       运行状态      阻塞状态

 

线程的状态?

创建,就绪,运行,阻塞,等待,死亡

 

进程通信的机制?

管道,消息队列,信号量,共享内存,套接字

 

操作系统为什么要分用户态和内核态?

  用户态下的程序不能直接访问操作系统内核数据结构和程序,执行一个程序时,大部分时间是运行在用户态下的,在需要操作系统帮助完成某些它没有权力完成的工作时就会切换到内核态。分为用户态和内核态的原因就是特权级的不同。

 

Linux的内核是一个有机的整体,每当用户进程进行系统调用时,都自动将运行模式从用户态转为内核态,此时进程在内核的地址空间中运行,当一个进程执行系统调用而陷入内核代码中执行时,我们就称处于内核态。当进程执行用户自己的代码时,就称为用户态

 

用户态切换到内核态的方式

1)系统调用

2)中断

3)异常

 

进程切换的过程(由内核进行)?

   1.保留当前进程的上下文

  2.在内存中检索下一个进程的上下文并在cpu的寄存器中恢复

   3.跳转到程序计数器指向的位置以恢复该进程

 

虚拟内存和物理内存?

  物理内存:是真实的内存(内存条)

  虚拟内存:磁盘空间中的一块逻辑内存

  以前只有物理内存的时候,每次开启一个进程都要给4G的物理内存,这样就导致很容易就将内存分配完,而没有分配到资源的进程就只有等待,引入虚拟内存后一个进程运行时得到的是4G的虚拟内存,实际上可能只占用一点物理内存,这4G是进程自己以为自己获得的,实际用了多小内存就对应多少物理内存而不是直接4G的物理内存

 

僵尸进程和孤儿进程?

    僵尸进程:子进程先于父进程退出后,子进程的pcb需要其父进程释放,但是父进程并没有释放子进程的pcb,这样的子进程就是僵尸进程,也就是其实已经死掉的进程

    孤儿进程:一个父进程退出后,它的一个或多个子进程还在运行,这些进程就会成为孤儿进程,会被init进程收养,并由init进程对他们完成状态进行收集工作

   区别:孤儿进程由于父进程已经死亡,所以系统会帮助处理孤儿进程,所以不占用资源,而僵尸进城占用着资源

 

50亿个int类型的正整数,怎么去重?

   采用bitmap,把数据放在bitmap中,然后遍历每次判断bitmap中是否有该值

 

内存碎片?

   内存碎片通常分为内部碎片和外部碎片

       内存碎片:由于采用了固定大小的内存分区,当一个进程不能完全使用分给它的固定内存区域时就产生了内部碎片,内存碎片不能完全避免

       外部碎片:由于某些未分配的连续内存区域太小,以至于不能满足任意进程的内存分配请求,从而不能被进程利用的内存区域

       现在采用的是段页式内存分配,将进程的内存区域分为不同的段,然后将每一段由多个固定大小的页组成,通过页表机制,使段内的页不必连续处于同一块内存区域,从而减少了外部碎片,但是仍然可能存在少量的内部碎片

 

 

为什么要有用户态和内核态?

由于需要限制不同的程序之间的访问能力,防止他们获取别的程序的内存数据,或者获取外围设备的数据,并发送到网络,cpu划分出两个权限等级——用户态和内核态

 

select和epoll?

    select和epoll都是I/Od多路复用模型,用于持续监听多个socket的

    select:会轮询各个socket,不管socket是否活跃,随着socket数量的增加,性能会主键下降

     epoll:采用了中断注册回调的方式,socket io就绪时发出中断,然后将socket加入就绪队列,它能够显著提高程序在大量并发连接中只有少量活跃的情况下的cpu利用率,epoll使用了内存映射技术将内核和用户控件指向同一块内存

    select的缺点:内核/用户数据拷贝频繁,操作复杂,轮询时间效率低

   epoll的优点:插入句柄时返回速度特别快,还能够有效的将发生事件的句柄给用户

 

Linux查看进程cpu使用率的命令?

   top

   top然后再输入1,就是查看每个核心的cpu使用率

 

 

什么是死锁?

   死锁就是多个线程或进程相互持有对方所需要的资源,又不主动释放自己持有的资源导致所有线程无法继续而陷入阻塞

 

什么是活锁?

   就是线程虽然没有阻塞,并且始终在运行,但是程序无法进行下一步,因为线程始终重复做相同的事情。

   解决方案:1.以太网的指数退避算法

                     2.加入随机因素

  例子:消息队列:如果消息处理失败,就在队列开头重试,但是一直失败,这样的话就算没有阻塞,程序也无法继续

             解决方案:将失败的消息放在队列尾部,加入重试次数的限制

 

如何避免死锁?

    1)避免一个线程同时获取多个锁

    2)避免一个线程在锁内占用多个资源,尽量保证每个锁只占用一个资源

   3)尝试使用定时锁替代阻塞式的锁

   4)对于数据库锁,加锁和解锁必须在一个数据库连接中

 

 

os层面如何解决死锁?

    死锁预防: 允许多个进程同时访问一个资源实例,禁止已持有资源的进程等待其他资源,申请的资源不能立即使用的话就释放

    死锁避免:利用额外的先验证信息,判断系统会不会出现死锁——银行家算法

    死锁检测与恢复:操作系统直接忽略死锁,由应用程序来处理死锁——鸵鸟算法

 

epoll水平触发和边缘触发?

  水平触发:只要读内核缓冲区非空,有数据可以读取,就会一直发出可读信号,只有有空间可以写入,那么就会一直发出可写信号,LT模式支持阻塞和非阻塞两种,epoll默认的模式就是LT

   边缘触发:当读内核缓冲区由空转换为非空时,发出可读信号通知,当写内核缓冲区由满转换为不满的时候发出可写信号进行通知。

    两者的区别就是水平触发只要读缓冲区有数据,就会一直发出可读信号,而边缘触发仅仅在非空变为空时才发出一次可读信号

 

 

如何检测进程是否出现了内存泄漏?

   可以通过pmap命令来查看

 

Linux下如何找出io读写很高的进程?

  通过iostat查看相关磁盘的使用信息,然后通过iotop找到占用高的进程

 

虚拟内存怎么到物理内存的?

     当每个进程创建的时候,内核会为进程分配4G的虚拟内存,当进程还没有开始运行时,这只是一个内存布局。实际上并不立即就把虚拟内存对应位置的程序数据和代码(比如.text .data段)拷贝到物理内存中,只是建立好虚拟内存和磁盘文件之间的映射就好(叫做存储器映射)。这个时候数据和代码还是在磁盘上的。当运行到对应的程序时,进程去寻找页表,发现页表中地址没有存放在物理内存上,而是在磁盘上,于是发生缺页异常,于是将磁盘上的数据拷贝到物理内存中。可以认为虚拟空间都被映射到了磁盘空间中(事实上也是按需要映射到磁盘空间上,通过mmap,mmap是用来建立虚拟空间和磁盘空间的映射关系的)

 

 

Linux中的"|"?

  管道,把前一个命令原本要输入到屏幕的数据当做后一个命令的标准输入

 

 

运输层和网络层的职能?

   运输层的作用:一方面为上层应用层提供进程的端到端的通信服务一方面屏蔽了下面网络层的细节,在逻辑上好像两个进程实体之间存在一条端到端的逻辑通信通道。功能:复用和分用

  网络层:处理跨越多个网络的机器之间的路由问题,同时也管理网络名称和地址,以便于解决路由问题。它处理从发送方到接收方的数据移动,必要时还能把数据重新打包到较小的数据容器中,处理和识别发送方和接收方的位置问题。功能:mtu分片,寻址,路由

 

多进程和多线程的区别?

  多进程的数据共享复杂,同步简单,占用内存多,切换复杂,cpu利用率低,进程间不会互相影响

  多线程共享数据简单,同步复杂,占用内存少,cpu利用率高,一个线程挂掉会导致整个进程挂掉

 

为什么进程切换的开销比线程大?

   每个进程都有自己的内存空间,所以进程间切换是内存空间的切换,而多个线程共享的是进程的内存空间,是在一个内存空间里进行切换的。

   进程切换时需要切换页表,而且经常伴随着页调度,而线程只需要保存线程上下文信息就行了

 

大量close_wait?

   被动关闭连接的一方在已经接收到主动方发送的fin后,但是自己还没发送fin给对方,这个时候连接处于close_wait状态,如果close_wait时间长或者有大量的clost_wait,可能是某种情况下对方关闭了socket连接,但是我方并没有关闭连接,也就是没有发送ack信号,于是这个资源就一直被程序占用

 

 

linux怎么创建进程和线程的?

   可以通过fork和vfork来创建进程,fork多一次内存拷贝,vfork比较麻烦还有风险。目前内核对fork做了写时拷贝优化,也就是说对于fork只有当你需要改变的时候才从父进程中拷贝到子进程中

  线程的创建:进程之间共享代码段,文件描述符,信号处理,全局变量的话就称为线程,如果不共享就是进程,线程创建是通过clone或者pthread_create来创建的

 

进程的管道通信方式的管道种类?

   匿名管道:在内核中申请一块固定大小的缓冲区,程序拥有写入和读取的权利,一般使用fork函数实现父子进程的通信

   命名管道:在内河中申请一块固定大小的缓冲区,程序拥有写入和读取的权利,没有血缘关系的进程也可以进程间通信

  特点:面向字节流,生命周期和内核相同,自带同步互斥机制,半双工,单向通信

 

Linux文件权限有哪些?

   r:可读 4

   w:可写  2

   x:可执行   1

777:用户组,用户,其他都能够读,写和执行

 文件权限的修改使用chmod

 

 

dns的域名解析过程?

   1.首先在浏览器中查询是否缓存了dns的记录

   2.如果浏览器中没有的话会去操作系统中查找

   3.操作系统中也没有的话就回去路由缓存中查找

   4.还是没有的话就去isp的dns服务器中查询请求,如果还是找不到,就会像根服务器发出请求,进行递归查询

 

ip地址是多少位的?为什么?

  ip地址是32位的,首先必须是8的倍数,这样方便计算机处理,32的话能够表示40亿台主机,当时认为就够用了,但是现在发现其实是不够用的,所以ipv6才使用的128位

转载地址:https://blog.csdn.net/qq_40058686/article/details/104436452 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:169.多数元素
下一篇:java基础

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月15日 05时10分49秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章