IO多路复用

使用IO多路复用(linux中通过epoll来实现)可能效率还并不能比得上多线程 + 同步阻塞的方法。其主要的优势在于能够处理更多的连接,多线程 + 同步阻塞IO的方式会开辟更多的线程,线程开启的开销还是比较大的,如果换做使用线程池,那么在多线程切换的时候实际上也消耗了部分时间。
针对连接较少的情况 :
多线程 + 同步阻塞IO的方式更加适合,因为其处理效率更高
针对IO并发量很大的情况:
开辟多线程实际上内存消耗、时间消耗较大,此时使用IO多路复用效果会更好

进程和线程的区别与联系

  • 进程是对运行程序的封装,是系统进行资源分配和调度的基本单位,而线程是进程的子任务,作为CPU资源分配和调度的基本单位
  • 进程的创建需要系统分配内存以及CPU,文件描述符等资源,销毁也需要进行相应的回收,所以进程的管理开销是比较大的,但是线程的开销则比较小
  • 进程之间并不会相互影响,但是一个线程崩溃可能会导致进程崩溃,从而影响其他线程
  • 联系 : 进程与线程之间关系:线程是存在进程的内部,一个进程中可以有多个线程、一个线程只能存在一个进程中;

进程、线程之间的通信方式

进程之间通信方式:

  • 管道 : 管道是属于半双工的,双方需要通信时,需要简历两个管道。管道实际上就是一个内核缓冲区,进程通过先进先出的方式从缓冲区中读取数据。对于匿名管道而言,其只能够支持父子进程之间的通信;而有名管道支持非亲缘关系进程之间的通信;
  • 信号量 : 信号量实际上是一个计数器,用于控制多个进程对共享资源的访问。信号量实际上只有等待以及发送两种操作,等待就是将其值减一或者挂起进程,发送就是将其值加一或者将进程恢复到运行状态;
  • 共享内存 : 共享内存允许两个或者多个进程共享一个给定的存储区,这一段存储区可以被两个或者多个进程映射到自身的地址空间中。当一个进程将某些信息写入到共享内存后,可以被其他使用这个共享内存的进程简单读取。其中共享内存的执行效率最高,但是需要使用锁或者其他机制进行同步;
  • 消息队列 ;消息队列是一个链表,是一系列保存在内核中消息的列表,用户进程可以向消息队列中按照一定规则添加新消息,也可以从消息队列中读取消息(消息队列可以不同按照队列次序进行读取,而是可以根据自定义条件接收特定类型的消息)
  • 套接字 : 套接口也是一种进程间的通信机制,与其他通信机制不同的是,可以用于不同机器间的通信

线程之间的通信方式:

  • 使用全局变量
  • 使用信号机制
  • 使用事件的方式通知

进程的一些调度方式

  • 先来先服务 : 按照作业达到任务队列的顺序调度,但是效率不高,性能不好。不利于短作业操作
  • 短作业优先 : 每次从队列里面选出预计运行时间最短的作业来运行 (不利用长作业)
  • 最短剩余时间优化 : 当某一个作业正在运行时,如果突然队列中进入某个作业更短时间运行,那么中断当前运行时间,选择处理时间更短的作业运行
  • 时间片轮转 : 将系统CPU处理划分为若干个时间片,进程按照先后顺序进行排列,每次都是调度队首的进程,当执行完一个时间片后,计时器发出时钟中断请求,并将该进程移动到队尾。该调度方式能够在某一时间段内相应所有的用户请求。

操作系统的内存管理

  • 物理内存管理
    • 单一连续分配 : 内存分为系统区和用户区,系统区仅供操作系统使用,用户去为用户提供;
    • 固定分区匹配 : 将用户内存空间划分为若干个固定大小的区域
    • 动态分区 ; 先将进程放入到内存中,然后根据进程的大小动态建立分区,但是通过该方式可能会出现一些内存碎片的问题
    • 非连续的内存分配管理方式:
      • 分页存储管理 : 通过页表进行关系映射,将用户程序的页号与内存中的块号进行映射(提高内存利用率)分页的思想在于 : 将主内存空间划分为大小相等且固定的块,块相对较小,其作为主存的基本单位。而每个进程以块为单位进行划分,进程在执行时以块为单位逐个申请主存中的块空间;
      • 分段存储管理 : 分段的目的是方便编程、信息保护和共享、动态增长以及动态链接等
      • 段页式存储管理 : 先将程序分段、每段再进行分页,所以正常来说需要查三次内存,先查段,在查页,最后查数据
      • 页和段的区别 : 页是物理单位固定大小系统定义,所以地址空间是一维的,程序员只要记一个地址符号就行了。段是逻辑单位用户定义,所以地址空间是二维的,既要给出段名,也要给出段内地址。
  • 虚拟内存管理

死锁产生的必要条件

  • 互斥 : 一个资源每次只能被一个进程所使用
  • 占用并请求 : 一个进程因请求资源而阻塞,对已经获得的资源不释放
  • 不可剥夺 : 进程在获得资源后,在没有使用结束前是不能够被强行剥夺的
  • 循环等待 : 若干个进程之间形成一种头尾相接的循环等待资源关系

死锁的原因 :

  1. 系统资源不足
  2. 进程运行推进顺序不当
  3. 资源分配不当

出现死锁,如何恢复?

  • 重新启动 ;但是其代价很大,不仅包括死锁的进程还有没有死锁的进程
  • 终止进程 : 终止参与死锁的进程并回收所占资源
  • 剥夺资源 : 剥夺死锁进程占有的全部或者部分资源
  • 进程回退 : 让参与死锁的进程回退到以前没有发生死锁的某一点
  • 另外还有银行家算法等,可以帮助你如何避免死锁

孤儿进程以及僵尸进程时为什么,如何形成的?

  • 孤儿进程是父进程执行完任务退出后,子进程还在执行任务。孤儿进程会被init进程收养并完成状态收集
  • 僵尸进程是子进程完成并退出后,父进程并没有使用wait或者waitpid对他们的状态进行收集,这些子金册灰姑娘的进程描述依旧还是会保留在系统中,这些子进程成为僵尸进程
  • 如何处理僵尸进程 :
    • 通过fork两次的办法,将子进程的父进程变为init进程
    • 子进程退出时,需要向父进程发送SIGCHID信号,通过这个信号父进程能够调用wait来处理僵尸进程