首先明确操作系统的几大模块:
1. 系统初始化
2. 进程管理
3. 文件系统
4. 存储系统管理
5. I/O管理
那么windows内核和Linux内核在这几个模块上有哪些相同之处呢?又有哪些不同之处呢?
首先,作为os,他们的理念都是相似的。
1. 一切皆文件。 可能读写文件很好实现把,linux不管修改个什么东东其实都是在修改文件
2. 进程是执行的实体。 几乎对于操作系统的一切操作,都要通过进程来实现的,这个才是管理资源的真正实体。
3. 中断。 在西电学习时,刘西洋做过这样一个比喻。一个操作系统其实就是一个主循环加中断,我觉得其实还是蛮生动的,很能突出中断对于整个操作系统的意义。
下面,对于windows和linux做一个简单的评析,以及提出一些在面试中遇到的问题,估计也是实际开发中的问题,内核之间肯定还是有不小区别的。
定位:windows vs linux
众所周知,windows是商用系统,面向大众的。既然是商用的,商用的很大一个特点就是向后兼容。而linux是开源系统,内核之间的升级很多时候并不兼容,主要是为了加入更多更新的东西把,但是升级真的很麻烦。
其次,windows只是pc领域的霸主,而linux在设计之初,很多时候是针对服务器的。这个也导致了他们在实现的很多区别。
系统初始化:
略。不是很关键吧。但是实现过程都应该差不多,有兴趣大家可以去查下。
进程管理:fork+exevc vs createProcess
Linux的进程创建函数?当然是fork了。Linux中进程本身是可以执行的。在windows中,进程只表示是资源的拥有者,不能单独执行,执行必须要一个线程。
fork()的含义是把进程本身clone一个新的出来。也就是说,fork之后子进程和父进程都执行同样的一段代码。想要区分,必须通过fork的返回值来区分。
int pid = fork();
if (pid < 0) {// printf("error");} //小于0,发生错误
else if( pid == 0 ) {// printf("子进程!");} //==0,为子进程
else{ // printf("父进程! ");} // >0,父进程
为什么这个样子呢?Linux主要应用于服务器。而服务器最多用到的是把同一个资源开辟很多个进程给n多个用户来同时使用啊。这样开销够小,响应够快。所以fork快速复制父进程,子进程直接使用父进程的地址。那么子进程需要执行其他的资源呢?用exevc族,这个时候才为子进程开辟自己的地址空间,传入需要执行的文件,就可以执行具体的内容了。
而windows中,createProcess有一大堆的参数,不过很多时候都默认为null。它的作用相当于fork+execv吧。
那么怎么理解linux和windows下的进程管理呢?
一个进程最基本的内容:PCB、程序段、数据段
一个线程包含的内容:线程ID,当前指令指针(PC),寄存器集合和堆栈组成。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
资源在外存上时候,往往都是代码、资源什么的,就是程序本身。而在内存上的时候,就有了进程,进程相当于代码的一次生命周期,准备了一些最基本的能为运行做准备的上下文情况。而进程总要在cpu上跑一次把,执行一条一条的指令,这个时候就是线程在管理,线程相当于进程的一次生命周期,它真正的活了一把啊。
那么os在执行时,就是进程线程都要准备好的。而linux在实现的时候,其实相当于是新建了很多指针指向同一块资源,能够直接给你执行,在运行时大家都控制处理它,够快吧。而在需要执行不同的文件内容时,才为他在内存中分配相应的内存空间,做个替换工作,就有新的实体了。而windows下进程是资源的拥有者,你们谁想用就新建个线程自己去跑吧。
文件格式:PE vs ELF
windows可执行文件格式是PE(portable and executable,可携带可执行)。而linux使用的ELF(executable and linkable format,可执行和可链接格式)。两者都有相似的东西,比如都分成了几个section,包括代码段,数据段等。但是两个又不一样。
由于windows内核固定,而linux内核之间往往不兼容。linux软件安装问题往往让人很抓狂。在windows中只需要next、next一步步继续就好了,而linux的软件包则有很多,.deb、.rpm、.tar.gz什么的。而内核版本不固定带来的效果是可以升级很快,但向后兼容问题则让我们抓狂的要死。安装过程往往需要更改软件依赖关系什么的!!!Oh, fucking linux。而这些内核理念上的不同很大程度上导致了他们文件格式的不同。
文件系统:ntfs vs ext2&ext3
NTFS 提供长文件名、数据保护和恢复,并通过目录和文件许可实现安全性。NTFS 支持大硬盘和在多个硬盘上存储文件(称为卷)。例如,一个大公司的数据库可能大得必须跨越不同的硬盘。NTFS 提供内置安全性特征,它控制文件的隶属关系和访问。从DOS或其他操作系统上不能直接访问 NTFS 分区上的文件。如果要在DOS下读写NTFS分区文件的话可以借助第三方软件;现如今,Linux系统上已可以使用 NTFS-3G进行对 NTFS 分区的完美读写,不必担心数据丢失。
Ext2是 GNU/Linux 系统中标准的文件系统,其特点为存取文件的性能极好,对于中小型的文件更显示出优势,这主要得利于其簇快取层的优良设计。
Ext3是一种日志式文件系统,是对ext2系统的扩展,它兼容ext2。
1、高可用性
2、数据的完整性
3、文件系统的速度 尽管使用ext3文件系统时,有时在存储数据时可能要多次写数据,但是,从总体上看来,ext3比ext2的性能还要好一些。这是因为ext3的日志功能对磁盘的驱动器读写头进行了优化。所以,文件系统的读写性能较之Ext2文件系统并来说,性能并没有降低。
4、数据转换 由ext2文件系统转换成ext3文件系统非常容易
5、多种日志模式
比较:从技术而言,windows在做这些方面真的很不入流。它对文件系统的以及设备的管理远远不及linux,windows下的刷新键不知道毒害了多少人呢?
Linux可以同时管理几千个处理器,windows呢?两个都够呛。Linux连续使用很多天,使用越来越快,windows一会就不行了。Linux的文件使用越多碎片就越少,windows一会就卡的要死。
中断与I/O:
1. 中断是由异步的外部事件引起的。外部事件与中断响应及中断响应与正执行的指令没有关系
2. 异常是执行指令器件检测到不正常的或非法的条件引起的。异常与正执行的指令有直接的联系。根据引起一场的程序是否可被回复和恢复点不同,把异常分为故障(fault)、陷阱(trap)和中止(abort)。
故障是在引起异常的指令之前,把异常情况通知给系统的一种异常。
陷阱是在引起异常的指令之后,把异常情况通知给系统的一种异常。
中止就是中止处理了
Windows中IRQL(Interrupt ReQuest Level)的概念,而linux中没有。
一个常规的IRQL如下:
31:高
30:掉点
29:处理器间中断
28:时钟
27:配置文件
26
。
。
。
3:设备中断(其实只用了16个)
2:DPC/调度
1:APC
0:无源
Windows中有32级,而linux中似乎只有5级。更多的优先级可以使响应各级服务时更加的好,但是嵌套深度太多总是容易带来一些不必要的麻烦。
相似之处:
都将中断分为了两部分。在LINUX中叫ISR(还是其他?)和BOTTOM HALF。而WINODWS中,DPC(Deferred Procedure Calls)和APC(Asynchronous Procedure Calls)就非常类似BOTTOM HALF。
以linux为例:
上半部响应中断,下半部分为中断处理函数。
下半部分处理机制有tasklet、工作队列、软中断
一. 软中断
软中断是静态分配的,这也就意味这如果想定义新的软中断就必须重新编译内核。软中断可以并发的运行在多处理器上,即使同一个软中断也是这样。所以,软中断函数必须是可重入函数,而且需要使用自选锁来保护数据结构。
二. tasklet
tasklet也是一种软中断,但是tasklet比软中断有着更好的并发特性。是io驱动程序首选的可延迟函数方法。tasklet有如下的特性:
(1)tasklet可以在内核运行的时候定义
(2)相同类型的tasklet不能在用一个CPU上并发运行,也不能在不同的CPU上并发运
(3)不同类型的tasklet不能在同一个CPU上并发运行,但是可以在不同的CPU上并发运行。所以如果不同的tasklet访问相同的数据结构,需要加一定的锁保护
三. 工作队列
工作队列由内核线程来执行。主要的数据结构是workqueue_struct结构。这个结构是是一个cpu_workqueue_struct的数组。cpu_workqueue_struct结构是工作哦队列的基本结构。主要有此工作队列工作的链表,还有内核线程的进程描述符的指针。 工作队列的工作是由work_struct结构组成,这个结构有需要执行的函数,以及传输的数据等字段。建立工作队列是一项非常耗时的操作,因为它会建立一个内核线程。所以linux默认建立了一个工作队列来供使用。每一个CPU一个这样的工作队列。
管理:
注册表
这个是windows特色,而linux中每个软件有自己的配置文件即可,灵活性很大
软件使用
其实windows下的软件绝大多数都有linux的对应东西。比如说word,在linux下使用latex做出来效果往往非常只好,而且不会因为移植问题二格式发生变化。用vim与ide相比呢?其实什么软件最好,当然是diy的了,定制的总是最好的咯
如何深入内核: shell?(常用命令)
Linux很多时候通过shell来访问内核,命令行模式为在经常接触内核的过程中算是个很好的选择了。总比windows下用资源浏览器或者ie总出现未响应要好得多吧。
内核树与补丁?
其实就是内核源码
Linux内核开发流程当前包括一些主内核分支,和很多不同的子系统专有的内核分支。它们是:
- 主 2.6.x 内核树
- 2.6.x.y -stable 内核树
- 2.6.x -Git 内核补丁
- 2.6.x -mm 内核补丁
- 子系统专有内核树和补丁
常用命令
cat 文件名 输出文件内容到基本输出(屏幕 or 加>fileName 到另一个文件)
cb 格式化源代码
chmod //chang mode,改变文件的权限
cp copy
date 当前的时间和日期
echo $abc 在变量赋值之后,只需在变量前面加一个$去引用.
lint 语法检查程序
ls dir
man help
more type
du 查看磁盘空间状况
ps 查看当前进程状况
who 你的用户名和终端类型
定义变量 name=abc? (bash/pdksh) || set name = abc (tcsh)
mkdir 创建目录
rmdir 删除目录
cd 进入目录
rm 删除文件
more 显示文件
echo 显示指定文本
mv 改文件名
pwd 显示目录路径命令
uname -r 查看自己的linux内核的版本
理念:
补丁? 真想不通windows为什么那么麻烦,有缺陷通过打补丁的方式,还不断的更新。有病毒买杀毒软件花钱,整理系统花钱,什么都花钱,费劲。
内核为何使用了C,而非C++?
根据linus torvalds的解释:C++语言想解决的问题都不对路,都是一些皮毛问题,而没有涉及真正深层次的问题。 C++的对象、模板和函数重载都基本上纯粹是C的语法扩展,是语法糖,总体上把C的语法和类型系统都弄得更糟。他建议,在系统编程里直接用C就可以,非系统编程里,应该选择一种有垃圾收集的语言,C++语言的特性基本无用,只会捣乱。因此,什么时候C++都不可能是正确的选择。
Linus也承认,在其他一些情况下,可能需要更多语言支持,语言级的内存分配机制如垃圾收集、并发、动态代码生成等等。但是内核开发不需要。
很多时候c++的stl、boost库都已经很成熟了,但是都有一定的编程模型什么的在里面。但是在对内核进行更改的时候,这些东西很可能让内核更改陷入困境。简洁就是美吧,抽象程度太高在某些时候未必奏效吧!!!
面试中常见OS问题:
进程与线程区别?线程安全?
进程状态切换?
死锁?死锁条件?
创建进程、子进程?
常见linux命令?
中断?Windows下linux下的区别?
IPC?那两大类?主要的ipc方式?
Linux建立工程编译等问题?
Linux编译内核?内核移植?
Socket编程?
Gdb调试程序?Makefile熟悉?
驱动开发熟悉否?编写驱动?
。。。
总评:
Windows在很多设计上远不及linux的。Windows好比一坨屎,大家都在吃屎;linux好比一个美女,大家想上而不得。没那么高的能力把,所以大家yy下linux还是回去接着吃屎吧!!!!