操作系统知识回顾(更新中,自用)

1 进程和线程的区别

  进程是操作系统分配资源的最小单位,进程就是一个正在运行的程序以及程序所需要的资源,包括内存资源、文件资源以及系统资源。
  那为什么要引入线程呢,原因是如果是单线程的进程在运行过程中需要等待某些资源的到来,那么此时CPU将空转,CPU资源就被白白浪费了。为了避免这种情况就引入了线程,一个进程下可以有多个线程,这多个线程可以各司其职,当其中一个线程等待资源时,可以调度另外一个线程来使用CPU,通过这样的方式可以来提高CPU利用率。
  除此之外,线程只有栈、程序计数器和寄存器等资源,所以创建、销毁一个线程以及线程的上下文切换都比进程的开销要小。进程与进程之间互相独立、互不干扰,但是线程与线程之间需要考虑线程安全问题,所以线程访问共享内存时需要进行同步。

2 协程

  协程是一个用户级的轻量级的线程,在某个子程序内部跳转到另外一个子程序运行,在恰当的时机又跳转到原来的子程序内部运行。
  协程有两个优点:
  1 协程上下文的开销小;
  2 不需要锁机制来同步,效率高,并发性比较好。

3 进程的状态有哪几种

  进程的状态主要是三种:运行态、就绪态、阻塞态,其中运行态和就绪态可以互相转换。
  1 运行态的进程时间片消耗完就会进入就绪态;
  2 就绪态的进程被调度会进入运行态;
  3 运行态的进程等待某些资源就会进入阻塞态;
  4 阻塞态的进程资源到达就进入就绪态。

4 进程调度算法

非抢占式的调度算法
  1 先来先服务算法:不公平
  2 短进程优先:会导致长进程饥饿,不公平

抢占式的调度算法
  1 最短剩余时间优先
  2 时间片轮转
  3 优先级
  4 多级反馈队列:结合了时间片和优先级的调度算法,设置多个队列存放就绪的进程,不同队列分配不同的时间片,时间片越小优先级越高。如果一个进程被调度仍然没有执行完成,那么放到下一个时间片更大的队列中去。通过这样的方式可以使一个长进程在较小的周期内执行完成。

5 Linux下创建进程的方法

  Linux下通过fork()系统调用来创建新的进程,通过fork的返回值来判断在子进程内还是在父进程内,返回值为0,代表在子进程内,返回值大于0代表在父进程内,返回值即为子进程的PID。
  fork()创建出来的子进程是父进程的一份拷贝,如果fork()之后立马exec(),让子进程放入内存运行,那么之前的拷贝就是多余的,所以这里涉及到了写时复制。
  写时复制 (copy on write)
  在fork之后,子进程没有进行写操作,那么子进程可以共享父进程的地址空间,等到进行写操作,才去进行相关数据的复制。通过这种方式来延迟拷贝动作或者说是避免不必要的拷贝,来提高效率。

6 僵尸进程、孤儿进程

  僵尸进程是子进程没有被正确销毁,会导致系统资源无法正常释放,是有危害的;孤儿进程是子进程还没结束,父进程先结束,这时候孤儿进程会被Init进程所接管,没有危害。

  一个子进程结束以后,需要被父进程通过wait()系统调用来接收子进程的信息后,才能释放相关的系统资源,比如PID号。如果系统中的僵尸进程过多,就会导致无法创建新的进程。

7 进程间通信的方法

进程间通信的方法主要有管道、消息队列、共享内存、socket。

1 管道分为匿名管道和有名管道
  匿名管道主要用于具有亲缘关系的进程通信,通过pipe系统调用创建管道,一端读一端写,管道的本质就是一块缓存区。
  有名管道可以用于不具有亲缘关系的进程通信,类似于读写文件。

2 消息队列

3 共享内存
  共享内存的实现机制是通过mmap将普通文件或资源映射到不同进程的地址空间中去,这样我们就可以像访问内存一样去访问共享的普通文件。

  共享内存如何同步
  主要是通过POSIX有名信号量,来对共享内存进行同步。通过sem_open来创建有名信号量。

4 不同主机上的进程通信使用socket

为什么要有虚拟内存

  在早期,呈现给编程人员的存储模型就是简单的物理内存。在这种情况下,想在内存中通时运行两个程序是行不通的。如果一个程序在某个位置写入一个新的值,将会擦掉第二个程序存放在相同位置的所有内存,所以同时运行两个程序是行不通的,这两个程序会立刻崩溃。
所以有了一种存储器抽象:地址空间。

  虚拟内存技术的作用:
  1 使多个进程有自己独立的内存空间,相互独立,互不干扰。
  2 可以处理内存超载,也就是可以使得大型程序运行在有限的物理内存中,允许程序在只有一部分被调入内存的情况下运行。
  3 使用分页技术,使得每个进程都可以被分割成很多块,一方面便于管理,另一方面比起分段式可以减少内存碎片,效率也更高。

你可能感兴趣的:(面试知识点(自用),c++,操作系统)