Contents

操作系统知识总结

操作系统知识总结

github链接欢迎star!

我的博客

进程,线程,协程

简述线程和进程,协程的区别和联系

区别

  1. 进程是对运行时程序的封装,是系统进行资源分配和调度的基本单元,而线程是进程的子任务,是CPU分配和调度的基本单元。
  2. 一个进程可以有多个线程,但是一个线程只能属于一个进程。一个线程可以有多个协程,一个进程也可以有多个协程。
  3. 进程的创建需要系统分配内存和CPU等资源,销毁时也要进行相应的回收,所以进程的管理开销很大;但是线程的管理开销则很小。
  4. 进程之间不会相互影响;而一个线程崩溃会导致进程崩溃,从而影响同个进程里面的其他线程。
  5. 线程和进程都是同步机制,而协程是异步机制。
  6. 协程不被操作系统内核管理,而完全是由程序控制。协程进行中断跳转时将函数的上下文存放在其他位置中,而不是存放在函数堆栈里,当处理完其他事情跳转回来的时候,取回上下文继续执行原来的函数。

联系

进程与线程之间的关系:线程是存在进程的内部,一个进程中可以有多个线程,一个线程只能存在一个进程中。一个线程可以有多个协程,一个进程也可以有多个协程。

进程的状态与状态转换

进程在运行时有三种基本状态:就绪态、运行态和阻塞态。

  1. 执行:进程分到CPU时间片,可以执行
  2. 就绪:进程已经就绪,只要分配到CPU时间片,随时可以执行
  3. 阻塞:有IO事件或者等待其他资源

各状态之间的转换:

  1. 就绪→执行 处于就绪状态的进程,当进程调度程序为之分配了处理机后,该进程便由就绪状态转变成执行状态。
  2. 执行→就绪 处于执行状态的进程在其执行过程中,因分配给它的一个时间片已用完而不得不让出处理机,于是进程从执行状态转变成就绪状态。
  3. 执行→阻塞 正在执行的进程因等待某种事件发生而无法继续执行时,便从执行状态变成阻塞状态。
  4. 阻塞→就绪 处于阻塞状态的进程,若其等待的事件已经发生,于是进程由阻塞状态转变为就绪状态。

什么是孤儿进程?僵尸进程?

  • 孤儿进程: 父进程退出,子进程还在运行的这些子进程都是孤儿进程,孤儿进程将被init进程(1号进程)所收养,并由init进程对他们完成状态收集工作。
  • 僵尸进程: 进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait 获waitpid 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中的这些进程是僵尸进程。

并发和并行有什么区别?

并发就是在一段时间内,多个任务都会被处理;但在某一时刻,只有一个任务在执行。因为切换速度足够快,所以宏观上表现为在一段时间内能同时运行多个程序。

并行就是在同一时刻,有多个任务在执行。这个是物理上的多个进程同时进行。

什么是内核态和用户态?如何实现两者之间的相互转换?

  • 为了避免操作系统和关键数据被用户程序破坏,将处理器的执行状态分为内核态和用户态。

  • 内核态是操作系统管理程序执行时所处的状态,能够执行包含特权指令在内的一切指令,能够访问系统内所有的存储空间。

  • 用户态是用户程序执行时处理器所处的状态,不能执行特权指令,只能访问用户地址空间。

  • 用户程序运行在用户态,操作系统内核运行在内核态。

处理器从用户态切换到内核态的方法有三种:系统调用、异常和外部中断。

  1. 系统调用是操作系统的最小功能单位,是操作系统提供的用户接口,系统调用本身是一种软中断。
  2. 异常,也叫做内中断,是由错误引起的,如文件损坏、缺页故障等。
  3. 外部中断,是通过两根信号线来通知处理器外设的状态变化,是硬中断。

锁,同步,通信

什么是死锁?死锁产生的必要条件?

死锁是指两个或两个以上进程在执行过程中,因争夺资源而造成的下相互等待的现象。产生死锁需要满足下面四个条件:

  • 互斥:一个资源一次只能被一个进程使用;
  • 占有并等待:一个进程至少占有一个资源,并在等待另一个被其它进程占用的资源;
  • 非抢占条件:已经分配给一个进程的资源不能被强制性抢占,只能由进程完成任务之后自愿释放;
  • 循环等待:若干进程之间形成一种头尾相接的环形等待资源关系,该环路中的每个进程都在等待下一个进程所占有的资源。

如何解决死锁问题?

解决死锁的方法即破坏产生死锁的四个必要条件之一,主要方法如下:

  1. 资源一次性分配,这样就不会再有请求了(破坏请求条件)。
  2. 只要有一个资源得不到分配,也不给这个进程分配其他的资源(破坏占有并等待条件)。
  3. 可抢占资源:即当进程新的资源未得到满足时,释放已占有的资源,从而破坏不可抢占的条件。
  4. 资源有序分配法:系统给每类资源赋予一个序号,每个进程按编号递增的请求资源,释放则相反,从而破坏环路等待的条件

你了解乐观锁和悲观锁吗?

  • 乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。适用于多读场景。
  • 悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。适用于多写的场景。

进程间通信的方式有哪些?

  1. 管道:管道这种通讯方式有两种限制,一是半双工的通信,数据只能单向流动,二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
  2. 消息队列:消息队列是消息的链表,存放在内核中并由消息队列标识符标识
  3. 信号(Signal):信号是一种比较复杂的通信方式,信号可以在任何时候发给某一进程,而无需知道该进程的状态。
  4. 共享内存:共享内存是映射一段能被其他进程访问的内存,这段共享内存由一个进程创建,但是多个进程可以访问。共享内存是最快的IPC方式
  5. 信号量(Semaphore):信号量是一个计数器,用来控制多个进程对资源的访问,通常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。
  6. 套接字(Socket):套接口也是一种进程间通信机制,它可用于不同主机间的进程通信

线程同步有哪些方式?

  • 信号量:允许统一时刻多个线程访问同一个资源,但需要控制统一时刻访问此资源的最大线程数量

  • 互斥量:实际上是信号量的一种特殊情况,允许统一时刻只有一个线程访问同一个资源

  • 信号,也叫事件:通过通知操作的方式来保证多线程同步,还可以方便实现多线程优先级的比较操作

多线程锁实现多线程同步

  • 互斥锁:保护临界区,确保同一时间,只有一个线程访问数据。如果互斥量已经上锁,调用线程会阻塞,直到互斥量被解锁

  • 自旋锁:在获取到锁之前,一直处于循环检测保持者是否已经释放了锁。与互斥锁的区别是,在申请自旋锁时,线程处于忙等状态,而非挂起状态

  • 信号量:一个计数器,用来控制多个进程对共享资源的访问。互斥锁为信号量的一个特殊情况。

  • 读写锁:高级别锁,区分读和写,符合条件时,允许多个线程访问对象。处于读锁时,允许其他线程和本线程的读锁,但不允许写锁。处于写锁时,任何锁操作都会睡眠等待

  • 递归锁:递归锁是互斥锁的一个特殊情况。同样地,只能由一个线程访问该对象,但允许同一个线程在未释放其拥有的锁时,反复对锁进行加锁操作

内存管理

了解虚拟内存吗?

每个程序都拥有自己的地址空间,这个地址空间被分成大小相等的页;但不需要所有的页都在物理内存中,当程序访问某个逻辑地址的时候,会去查看页表,如果页表中没有相应的物理地址,说明内存中没有这页的数据,发生缺页异常,这时候进程需要把数据从磁盘拷贝到物理内存中。这样,对于程序来说,逻辑上似乎有很大的内存空间,只是实际上有一部分是存储在磁盘上,因此叫做虚拟内存。

什么是分页?什么是分段?两者有什么区别?

  • 页式存储:把内存空间划分为大小相等且固定的块,因为程序数据存储在不同的页面中,而页面又离散的分布在内存中,因此需要一个页表来记录映射关系,以实现从页号到物理块号的映射。

  • 段式存储:用户进程地址空间按照自身逻辑关系划分为若干个段(segment)(如代码段,数据段,堆栈段),内存空间被动态划分为长度不同的区域,分配时以段为单位,每段在内存中占据连续空间,各段可以不相邻;

  • 段页式存储:用户进程先按段划分,段内再按页划分,内存 划分和分配 按页。

  • 分页主要用于提高内存利用率,实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。

软链接和硬链接有什么区别?

软链接可以理解为 Windows 的快捷方式。当源文件被删除了,链接文件就打不开了。因为记录的是路径。

硬链接就是记录着文件名和源文件的inode编号。

页面置换算法有哪些

在程序运行过程中,如果要访问的页面不在内存中,就发生缺页中断,将磁盘中该页调入内存中。此时如果内存已无空闲空间,系统必须从内存中调出一个页面到磁盘中来腾出空间。这种现象叫做缺页置换。当前操作系统最常采用的缺页置换算法如下:

  • 先进先出(FIFO)算法:置换最先调入内存的页面,即置换在内存中驻留时间最久的页面。性能较差,调出的页面可能是经常访问的
  • LRU算法:置换最近一段时间以来最长时间未访问过的页面。
  • LFU算法:缺页时,置换访问次数最少的页面

参考资料