1.什么是操作系统内核
操作系统内核是计算机上最低层的软件,提供计算机最核心的功能,比如:进程管理、内存管理、I/O管理、文件管理、网络管理
2.内核如何发挥作用?CPU是怎样执行的内核函数?
系统中断程序分为:用户程序(程序员自编代码)和系统内核程序(固定的程序)。CPU执行两种程序时的状态不同:用户态和核心态。用户程序通过中断或异常使CPU的执行状态发生改变,如,CPU在用户态执行用户程序,通过中断,CPU转而去执行核心态的内核函数。
3.内核与用户空间之间的区别是什么?
内核在内核空间中运行,在用户空间运行的正常程序,用户空间基本上是沙拳的一种形式,它限制用户程序,使他们不能惹的内存的其他程序或操作系统内核拥有。
内核是操作系统的核心,通常可以完全访问所有内存和机器硬件(以及机器上的所有其他内容)为了使机器尽可能稳定,通常只需要在内核模式/内核空间中运行最受信任,经过良好测试的代码。
内核模式的代码可以无限制地访问所有处理器指令集以及全部内存和I/O空间。如果用户模式的进程要享有此特权,它必须通过系统调用向设备驱动程序或其他内核模式的代码发出请求。
4.解释进程和线程的区别
进程是资源分配的最小单位,线程是程序执行的最小单位。
进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段,堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费要比进程要小得多,同时创建一个线程的开销要比进程要小很多。
线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式进行。
多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
5.线程同步机制
同步的实现方式有六种:互斥锁,自旋锁,读写锁,条件变量,屏障,信号量。
互斥锁:在访问共享资源前对互斥量进行加锁,访问完成后释放互斥量进行解锁。对互斥量加锁以后,任何其他试图再次对互斥量加锁的线程都会被阻塞,直至当前线程释放该互斥量。
自旋锁:自旋锁与互斥量类似,但它不使线程进入阻塞态,而是在获取锁之前一直占用CPU,处于忙等自旋状态。自旋锁适用于锁被持有的时间短且线程不希望在重新调度上花费太多成本的情况。
读写锁:读写锁有三种状态:读模式加锁、写模式加锁和不加锁,一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。读写锁非常适合对数据结构读的次数远大于写的情况。
6.死锁
死锁问题的产生是由两个或者以上线程并行执行的时候,争夺资源而互相等待造成的。当两个线程是为了保护两个不同的共享资源而使用了两个互斥锁,那么两个互斥锁应用不当的时候,可能会造成两个线程都在等待对方释放锁。在没有外力的作用下,这些线程会一直相互等待,就没法运行,这种情况下就发生了死锁。
在 Linux 下,我们可以使用pstack+gdb工具来定位死锁问题。然后使用 gdb 工具进一步确认。
避免死锁问题的发生:
必要条件:互斥条件、持有并等待条件、不可剥夺条件、环路等待条件
常见可执行的就是使用资源有序分配法,来破坏环路等待条件。
7.虚拟内存的概念和作用
虚拟内存是一种内存管理技术,是虚拟的、逻辑上存在的存储空间。
虚拟内存是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的、一致的和私有的地址空间。
虚拟内存工作原理:当进程开始运行时,先将一部分程序装入内存,另一部分暂时留在外存;当要执行的指令不在内存时,由系统自动完成将它们调入内存的工作;当没有足够的内存时,系统自动选择部分内存(暂不执行的程序)空间,将其中原有的内容交换到磁盘上,并释放这些内存空间供其他进程使用。
这样做的结果使程序的运行丝毫不受影响,使程序在运行中感觉到拥有一个不受内存容量约束的、虚拟的、能够满足自己需求的存储器。
三大作用:
- 缓存: 将主存看做一个存储在磁盘空间上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据。
- 内存管理: 为每个进程提供了一致的地址空间,简化内存管理。
- 内存保护: 保护了每个进程的地址空间不被其他进程破坏。
8.分页和分段的区别
分页:将程序的逻辑地址空间划分为固定大小的页(page),而物理内存划分为同样大小的页框(page frame)。程序加载时,可将任意一页放人内存中任意一个页框,这些页框不必连续,从而实现了离散分配。
分段:在分段存储管理中,将程序的地址空间划分为若干个段(segment),这样每个进程有一个二维的地址空间。每个段分配一个连续的分区,而进程中的各个段可以不连续地存放在内存的不同分区中。程序加载时,操作系统为所有段分配其所需内存,这些段不必连续。
分页和分段的区别:页的大小是固定的,由操作系统决定,而段的大小不固定,取决于我们当前运行的程序。分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,它含有一组其意义相对完整的信息,在程序中可以体现为代码段,数据段,是为了满足用户的需要。分页的作业地址空间是维一的,即单一的线性空间,程序员只须利用一个记忆符,即可表示一地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。段一般比页大,因而段表比页表短,可以缩短查找时间,提高访问速度。
9.用户进程间通信主要哪几种方式?
管道:管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
命令管道:命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
信号:除了用于进程间通信外,进程还可以发送信号给进程本身。
消息队列:消息队列是消息的链接表,包括Posix消息列system V消息队列。对足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
信号量:主要作为进程间以及同一进程之间的同步手段。
套接字:更为一般的进程间通信机制,可用于不同机器之间的进程间通信。