本节书摘来自异步社区《操作系统真象还原》一书中的第0章,第0.18节,作者:郑钢著,更多章节内容可以访问云栖社区“异步社区”公众号查看
0.18 编译型程序与解释型程序的区别
解释型语言,也称为脚本语言,如JavaScript、Python、Perl、PHP、Shell脚本等。它们本身是文本文件,是某个应用程序的输入,这个应用程序是脚本解释器。
由于只是文本,这些脚本中的代码在脚本解释器看来和字符串无异。也就是说,脚本中的代码从来没真正上过CPU去执行,CPU的cs:ip寄存器从来没指向过它们,在CPU眼里只看得到脚本解释器,而这些脚本中的代码,CPU从来就不知道有它们的存在。这些脚本代码看似在按照开发人员的逻辑执行,本质上是脚本解释器在时时分析这个脚本,动态根据关键字和语法来做出相应的行为。因此脚本中若出现错误,先前正确的部分也会被正常执行,这和编译型程序有很大区别。
顺便猜想一下解释型语言是如何执行的。我们在执行一个PHP脚本时,其实就是启动一个C语言编写出来的解释器而已,这个解释器就是一个进程,和一般的进程是没有区别的,只是这个进程的输入则是这个php脚本,在php解释器中,这个脚本就是个长一些的字符串,根本不是什么指令代码之类。只是这种解释器了解这种语法,按照语法规则来输出罢了。
举个例子,假设下面是文件名为a.php的PHP代码。
<?php 这是php语法中的固定开始标签
echo "abcd"; 输出字符串abcd
?> 固定结束标签
PHP解释器分析文本文件a.php时,发现里面的echo关键字,将其后面的参数获取后就调用C语言中提供的输出函数,如printf((echo的参数))。PHP解释器对于PHP脚本,就相当于浏览器对于JavaScript一样,不过这个可完全是我猜测的,我不知道PHP解释器里面的具体工作,以上为了说清楚我的想法,请大家辩证地看。
而编译型语言编译出来的程序,运行时本身就是一个进程。它是由操作系统直接调用的。也就是由操作系统加载到内存后,操作系统将CS:IP寄存器指向这个程序的入口,使它直接上CPU运行。总之调度器在就绪队列中能看到此进程。而解释型程序是无法让调度器“入眼”的,调度器只会看到该脚本语言的解释器。