不积跬步无以至千里

记录精彩的程序人生

  • 首页
  • Java
  • Golang
  • PHP
  • Python
  • Nodejs
  • Lua
  • Docker
  • DevOps
  • 文章归档
  • 默认分类
  • 关于
  • 标签

  • 搜索
PostgreSQL hbase 时间同步 nexus 开机启动 nexus, 开机启动 jenkins安装配置 gitlab安装配置 gitlab安装 文件系统 fastdfs gcc切换 gcc升级 mysql8 交换空间 虚拟内存 tcp thrift lua tag test VPN SoftEtherVPN homebrew asm spring tomcat maven jdk ios mac 图案字符 figlet mysql半同步复制 mysql主从同步 一主多从 一主一从 主从同步 反向代理 密码重置 test 虚拟机扩容 swap 虚拟空间 docker ldocker grpc-gateway protobuf 微服务 go grp GRPC 授权登录 OAuth2.0 SOA supervisord supervisor RPC CentOS rabbitmq 环境变量 php-fpm php.ini error php7 lnmp 编译安装 mysql nginx linux java php python redis 字符串操作 mysql5.7 Solo

Linux架构介绍

发表于 2020-08-07 | 分类于 默认分类 | 0 | 阅读次数 1309

我们以下图为基础,说明Linux的架构(architecture)。(该图参考《Advanced Programming in Unix Environment》)

最内层是我们的硬件,最外层是我们常用的各种应用,比如说使用firefox浏览器,打开evolution查看邮件,运行一个计算流体模型等等。硬件是我们的物质基础,而应用是我们所要奋斗的目标,但在两者之间,还要经过一番周折。

还记得我们在Linux启动的时候。首先会启动内核 (kernel),内核是一段计算机程序,这个程序直接管理管理硬件,包括CPU、内存空间、硬盘接口、网络接口等等。所有的计算机操作都要通过内核传递给硬件。

为了我们方便调用内核,我们将内核的功能总结成为系统调用(system call)。系统调用看起来就像是的C语言函数,你也可以在程序中直接调用。Linux系统有两百多个这样的系统调用。系统调用给了上层程序一个清晰的接 口,隐藏了内核的复杂结构。一个操作系统上的功能可以看作是系统调用的组合的效果,而且一个操作系统不可能作出超越系统调用的动作。可以说一个系统调用函 数就像是汉字的一个笔画,任何一个汉字都要由基本的笔画(点、横、撇等等)构成,而且我们不能臆造出笔画。在命令行中输入$man 2 syscalls可以查看所有的系统调用。你也可以通过$man 2 read来查看系统调用read()的说明。在这两个命令中的2都表示我们要在2类(系统调用类)中查询 (具体各个类是什么可以通过$man man看到)。

由于系统调用非常基础,所以有时使用起来很麻烦。比如说一个简单的给变量分配内存空间的操作,就需要动用多个系统调用。Linux定义一些库函数(library routine)来将系统调用组合成某些常用的功能,以方便我们编程。比如上面的分配内存的操作,看以定义成为一个库函数(像malloc()这样的函 数)。再比如说,在读取文件的时候,系统调用要求我们设置好所需要的缓冲。我们这个时候可以使用Standard IO库中的读取函数,而这个读取函数既负责设置缓冲,又负责使用读取的系统调用函数。使用库函数对于机器来说并没有效率上的优势,但可以把程序员从细节中 解救出来。库函数就像是汉字的偏旁部首,它由笔画组成,但使用偏旁部首更容易组成字,比如"铁"。当然,你也完全可以不使用库函数,而直接调用系统函数,就像“人”字一样,不用偏旁部首。

(实际上,一个操作系统要称得上是UNIX系统,必须要拥有一些库函数,比如ISO C标准库,POSIX标准等。)

至于shell,可以看作一种特殊的应用。实际上我们之前所说的命令行,就是shell。shell是一个命令解释器(interpreter),当我们输入“ls -l”的时候,它将此字符串解释为1) 在默认路径找到该文件(/bin/ls),2) 执行该文件,并附带参数"-l"。我们之前用>表示重新定向,用|表示管道,也是通过shell进行理解&或者|的含义,再通过系统调用指挥kernel建立具体的重定向或者管道机制。在没有图形界面之前,shell充当了用户的界面,当用户要运行某些应用的时候,要通过shell输入命令,以建立运行程序。shell可以执行符合shell语法的文本,这样的文本叫做shell脚本(script)。我们可以在图中看到,shell下通系统调用,上通各种应用,同时还有许多自身的便利可以使用,这些条件让shell脚本可以实现非常强大的功能。UNIX的一条哲学是让每个程序尽量独立的做好一个小的功能。而shell充当了这些小功能之间的"胶水",让不同程序能够以一个清晰的接口(文本流)协同工作,从而增强各个程序的功能。(这也是我们鼓励多用shell,少用图形化界面的原因之一。)

(shell也有很多种,最常见的是bash, 另外还有sh, csh, tcsh, ksh。它们出现的年代不同,所支持的功能也有差异。)

一个使用bash shell的终端

一个shell对应一个终端 (terminal)。曾经来说,终端是一个硬件设备,用来输入并显示输出。如今,由于图形化界面的普及,终端往往就像上图一样,是一个图形化的窗口。你 可以通过这个窗口输入或者输出文本。这个文本直接传递给shell进行分析解释,然后执行。

最后,我们进入一般的应用。应用是一个程序,它可以1) 直接调用系统函数 2) 调用库函数 3) 运行shell script。这些应用可以由多种语言开发(当然,最常见的是C语言),以满足我们使用计算机的各种需要。

我们可以看到,Linux利用kernel实现软硬件的对话。通过系统调用的这个重 要的接口,Linux将上层的应用与下层的kernel完全分离开,为程序员隐藏了底层的复杂性(相应的,也提高了上层应用的可移植性)。当我们在升级 kernel的时候,也可以保持系统调用的语句不变,从而让上层应用不感受到下层的改变。库函数利用系统调用创造出模块化的功能,而shell则提供了一 个用户界面,并让我们可以利用shell的语法编写脚本,以整合程序。

而所有的这些安排也为其他应用的开发提供了便利。

WEB架构师成长之路
Linux命令行与命令
  • 文章目录
  • 站点概览
ken

ken

记录精彩的程序人生

498 日志
9 分类
77 标签
RSS
Creative Commons
Links
  • 酷壳
0%
© 2010 — 2025 ken
由 Halo 强力驱动
鄂ICP备18013899号-1