在大学里,你可能学的是c,c++,java....到社会上工作后,你有可能换成其它语言了,这没办法,毕竟决定权不在我们手上,饭碗规定要用go,要用rust你都会马上去学习,就算饭碗决定你用asp你也得上,毕竟人在江湖人不由已,虽然有时候我们会听到某某语言天下第一,某某语言如何如何,有时候甚至跟别人吵一架,但是别人的饭碗有可能就是用这个语言的。在我们每个人的心中都可能觉得自己的东西才是最好的,别人的东西不行。
不过你在用什么语言,什么工具,反正只要能糊口,保住饭碗就是好语言,工作数年后,我们用的语言可能很多,但是我们的项目大部分都是运行在最流行的操作系统之上Linux,Linux系统源码,工作多年的朋友也知道整个系统90%以上都是c源码写成,我们的程序都要在上面运行,虽然我们用着各种编程语言,php,python,java,c++,c,rust,go,nodejs,lua,ruby...等,虽然我们每天都在为哪个语言最好,哪个框架最好,哪个库最好而争吵没有达成大家心中的想法,但是大家是否想过,我们的程序写好的源码最终是要在用c编写而成的Linux系统上运行!linux 提供的系统api接口都是一样的,特别是核心接口,我们的程序最终都要用系统提供的系统调用函数API。只不过上层语言做了各种封装形成了各种写法开发布而成的应用,包括我们的各种编译器,汇编器,各种开发库。
大学的朋友多少也撸过c,也知道撸好了需要编译,如果大学里的是直接在win上开始学的话,可能你四年都没有装过编译器,如果你在linux上或是其它嵌入式芯片,那么编译器种类特别多,有PC的,有ARM的,avr单片机的等,这些编译器最终会把我们写的各种源码会解释成汇编,这个时候它只要连接一下一些重要的库,特别是系统重要的库函数就可以启动了。
c,c++,java,go,嵌入式c等都需要编译器处理输出目标文件,而这个目标文件含有大量的数据,并且会分门别类的存储好。在linux系统中如go
大家也晓得,当我输入./go run xx.go文件后它就可以运行了
同样看java
同样看python
再看php
我相信大家应该看到共同点了,虽然大家用的编程语言不同,但是没有关系,我们还是有共同的话题,如果你感兴趣且不在乎什么语言的话
大家可以看出
- 它们是ELF文件
- 它们的标识是LEF 64-bit LSB
- 它们都要依赖/lib64/ld-linux-x86-64.so.2 当然linux发行版本不同也没有什么关系,你多少也能看出共同点。
我相信大家肯定听过动态库和静态库的概念,而上面的.so文件其实就是一个动态库文件,我画线的呢是它们java,go,python,php运行时会加载起来,它可以作为程序的一部分进行映射,你可以当作一个函数库,加载进来以后,我们就可以调用它提供的函数了,而这些函数是Linux操作系统提供的比较重要的一些函数了,这些.so文件它们也是ELF文件的一种
我们可以通过nm命令可以查看它提供了哪些函数
大家可以看我有线画出来了,左边是函数的地址,右边是函数的名称,当我们加载此库后,可以调用execve函数,我相信做Android,ios开发的伙伴应该用过.so文件【c++,c这些朋友是非常熟悉了】
那么接下来,我们运行一下各种编程语言写的程序并跟踪系统调用System call
- 看看go语言
这go语言啊语法是长这样的,语法规定,写法是由开发的那一批人规定的,毕竟人家的编译器就是专门识别这种写法,如果大家有相应的实力开发自己的编译器,那么我相信你,自己折腾一套编程语言也没有问题【我知道有的伙伴大学就撸过了,但是不出名^_^】
现在我运行一下
大家可以看到,我们调用了linux提供的execve函数,它在libc.so库中,这个库是Linux给我们提供的
它会去打开这个动态库,当然了c,c++程序员调用它提供的函数也是非常简单方便
大家可以看到go这个ELF文件,它本身是把Linux提供的libc.so中提供的execve做为启动时运行的第一个函数【我并没有提bash进程接收命令后的进一步系统调用,大家有兴趣可以关注我,详细聊】
它打开了demo.go文件做了什么处理,当然它知道^_^
好现在我们来看java的程序
同样要调用execve
好我们再看php
那么剩余的python道理一样。
看完上面的演示,我相信大家应该有一个认识,虽然语言写法不同,但是它们的系统调用都是一样的,大家应该往深的方向看,不要局限于表面的编程语言,脚本语言。
我们知道这些语言的写法五花八门,这些语言的函数,构建起来的应用都在是用Linux 提供的API,这些API都是c定义的API,我们可以非常方便的查阅它,相反Win提供的系统API查起来麻烦,写法也复杂。函数名长的要命。
大家一起这函数,就非常清晰的知道,哦原来是根据文件filename执行它,并且把argv当做参数传递给它,这样我们就知道原来我执行php,java,go,python它们会执行这个才加载我写的程序的。
我相信大家不管学什么编程语言,都会遇到多进程,多线程,网络编程方面的内容,除非靠着这些语言撸好的框架进行crud 工作,当然我也是这样以前。它们的写法用法不同,但是低层的东西是相同的。大家不要迷惑于语言的表面用法。
如果大家觉得有意义或是有必要,对这方面,多进程编程,网络编程感兴趣的朋友可以watch my video
video link:https://edu.51cto.com/sd/75a3d
有疑问加站长微信联系(非本文作者)