假设你没有可用的操作系统(OS),或者出于某种原因不能使用操作系统。然后,你将自己完成几乎所有的事情:内存管理、中断处理、与I/O设备通信、管理文件、配置和管理网络栈,等等。
从技术上讲,操作系统并不是严格需要的。有些系统没有操作系统。这些通常是占用空间很小的嵌入式系统:想想物联网信标。除了一个应用程序之外,它们根本没有可用的资源来保留其他任何东西。例如,在Rust中,你可以使用它的核心和标准库在裸机上运行任何应用程序( https://oreil.ly/zW4j7 )。
操作系统承担了所有这些无差别的繁重工作,将不同的硬件组件抽象出来,并为你提供一个(通常)干净和设计良好的应用程序编程接口(API),例如,我们将在第2章中仔细研究的Linux内核。我们通常将操作系统公开的这些API称为系统调用(syscall)。高级编程语言(如Go、Rust、Python或Java)构建在这些系统调用之上,可能将它们包装在库中。
所有这些都可以让你专注于业务逻辑,而不必自己管理资源,还可以照顾到你想要在上面运行应用程序的不同硬件。
让我们看一个系统调用的具体例子。假设我们想要识别(并输出)当前用户的ID。
首先,我们看一下Linux系统调用getuid(2)( https://oreil.ly/md15Z ):
这个getuid系统调用是我们可以从库中以编程方式使用的。我们将在2.3.6节中更详细地讨论Linux系统调用。
你可能想知道(2)在getuid(2)中是什么意思。这是man实用程序(想想内置的帮助页)用来指示在man中所分配的命令部分的术语,类似于邮政代码或国家代码。这是UNIX遗产显而易见的一个例子,你可以在1979年的UNIX Programmer's Manual第七版第1卷中找到它的起源。
在命令行(shell)上,我们将使用等效的id命令,该命令反过来使用getuid系统调用:
既然你已经基本了解了为什么在大多数情况下使用操作系统是有意义的,那么让我们继续讨论Linux发行版的主题。