计算机系统的理解一

  爱钻牛角尖的毛病又来了。仅仅是因为以前的一个c语言free内存报错。

  我们知道,malloc分配的内存是从堆里获得的,而堆是由操作系统维护的,也就是说,在没有malloc前,内存空间是不属于该进程空间的,malloc函数务必调用了操作系统的系统函数(参考前边linux内存管理heap篇可知,是brk和sbrk)。也就是说,brk和sbrk是linux的系统调用,在没有linux系统之前,是没有这两个函数的。比如我之前写过的DSP裸机驱动,虽然也是用的c语言,但是是不可能有brk和sbrk及malloc函数的。brk和sbrk函数向操作系统申请内存时,操作系统会打破该进程原有的虚拟地址空间(准确的说是增加虚拟地址空间),操作系统负责维护新增的虚拟地址和物理地址的映射(需要硬件MMU等的支持,这里暂不讨论)这时候,申请过的对空间就和该进程空间融合到一起了。内存使用完毕后,调用free函数释放内存时,其实没有被真正的释放,操作系统维护堆内存的方式是通过chunks,free时仅仅是把chunks标记为可用状态(参考上一篇博客),操作系统维护这些chunks是用了一个结构体:

struct mem_control_block { 
    int is_available;    //这是一个标记? 
    int size;            //这是实际空间的大小 
    };

当我们free时,实质是:

 void free(void *ptr)  
{ 
       struct mem_control_block *free; 
       free = ptr - sizeof(struct mem_control_block); 
       free->is_available = 1; 
       return; 
}

  当该进程下一次通过malloc申请内存时,操作系统首先会检查该进程空间的chunks,如果有chunks可用,就直接使用,否则才会调用brk和sbrk系统调用来重新分配内存,这样做的好处时,可以减少不必要的系统调用,提高效率,因为系统调用是很耗系统资源的。
  由此,再加上我做DSP裸机驱动的经验,可以大概探测出整个计算机硬件和操作系统及编译器之间的联系:硬件支持二进制指令,通过二进制指令开发出一种程序,这种程序可以翻译我敲进去的会变得代码,这个程序就是汇编编译器。通过汇编语言开发一种程序,这种程序可以把c源码翻译成汇编,再交由汇编编译器翻译成为二进制,这种程序就是c语言编译器。通过c语言编译器开发一种程序,这种程序可以对计算机硬件进行管理,并且可以有多进程的功能……这种程序就是计算机操作系统比如linux。开发linux时可能也是有一个c语言的主函数,但是不会有brk和sbrk、malloc、free、printf等等这些函数(刚好紧接着我就看了描写linus的一篇文章:

李纳斯认为,Unix 是一个简洁、干净的操作系统,在 Unix 上的大部分任务都是通过一些基本操作完成的,这些操作被成为「System Call」,顾名思义,这些操作就是你对系统的呼叫,系统通过响应你的呼叫完成工作。比如 fork、clone(创建子进程),比如 open、close、read、write(文件访问)。这些基本的系统调用通过组合可以完成大部分功能。同时,Unix 还提供了极为强大的IPC(进程间通信)方式:pipe(管道)。很多工作在GUI(图形界面)软件环境下的读者,最常用的IPC操作可能是复制、粘贴、鼠标拖拽,这些操作虽然简单,但是必须由人来完成,想要自动化就很困难。而这些在 Unix 上实现起来就像大自然一样自然,你只需要在程序之间开辟出一段缓冲区作为管道,然后父进程和子进程就可以通过这个管道实现进程间通信了。举个例子,以前给大家介绍的查找历史命令的脚本,就利用了管道的功能,如下:

history | grep apache

这行命令的含义就是查找包含 apache 的历史命令,其中特殊字符【 | 】用来告诉命令行解释器(Shell)将前一个命令的输出通过「管道」作为接下来的一行命令的输入,就这样,一个简单的进程间通信就完成了。

),因为这些函数都是起作用在linux之上的。那为什么我们在linux系统之写c源码时,就可以使用printf、brk、malloc等等这些函数了呢?开发linux系统时不能使用,现在为什么就能使用了呢?问这个问题的人还是混淆了编译器和库(也就是写好的调用,写好的程序)的概念。linux操作系统上的编译器还是开发那个开发linux系统时的编译器,功能一点都没有增加,但是多了许多库可以调用。就好比,一个人来到一个荒漠,他通过自己的能力构建了一个豪华别墅,并且把别墅预留了很多接线口,水龙头等,虽然说,人还是那个人,还是只有能的功能,但是这时候他已经可以通过。同样是我写完这篇文章后紧接着看到的描写linus那篇文章中,linus也用房子做了比喻,而且linus也是不用怎么学习物理,就能够学得非常好:

等待的过程中,李纳斯也没闲着,他又开始编程了。好的程序员对编程的喜爱是溢于言表的,以下摘录一些李纳斯的编程感想:

对于喜爱编程的人来说,编程是世界上最有趣的事,比下棋有趣得多!因为你可以自己制订游戏规则,而你制定什么样的规则,也就会随之出现与此规则相符合的结果。

在电脑世界中,你就是创世者,你对所发生的一切拥有最终的控制。如果你功力深厚,你可以是上帝――在一个较小的层面上。

你可以建筑一个这样的房子,有一个活板门,既稳固又实用。但是每个人都可以看出一个仅仅以坚固实用为目的的树上小屋和一个巧妙地利用树本身特点的美妙小屋之间的差异。这是一个将艺术和工程融为一体的工作。编程与造树上小屋有相似之外……在编程中,实用的考虑往往被置于有意思、美观优雅或有震撼力的考虑之后。

在代码的世界里,李纳斯就是一个诗人!

posted on 2014-07-02 11:14  滴石之水  阅读(286)  评论(0编辑  收藏  举报

导航