Operating system 有人能给我解释一下编程语言中的系统调用吗?

Operating system 有人能给我解释一下编程语言中的系统调用吗?,operating-system,Operating System,几天前我开始学习操作系统的概念,现在已经遇到了一些问题。 主要是我对系统调用非常好奇。 我了解到每个操作系统都提供自己的API (如Windows for Windows API、Linux for libc等) 我开始感到困惑的是包装器函数。 例如,Linux有一个fork()包装函数。 这是否意味着此函数中的算法执行系统调用例程 基于操作系统的系统调用表? 我不明白用C写的是什么意思。 这是否意味着它使用的是C标准库?或者仅仅是C编译器? 另外,为什么C编译器会编译它的标准库呢 有不同种类的

几天前我开始学习操作系统的概念,现在已经遇到了一些问题。 主要是我对系统调用非常好奇。 我了解到每个操作系统都提供自己的API (如Windows for Windows API、Linux for libc等)

我开始感到困惑的是包装器函数。 例如,Linux有一个fork()包装函数。 这是否意味着此函数中的算法执行系统调用例程 基于操作系统的系统调用表? 我不明白用C写的是什么意思。 这是否意味着它使用的是C标准库?或者仅仅是C编译器? 另外,为什么C编译器会编译它的标准库呢 有不同种类的编译器,如GCC windows C编译器等。? 我好奇的是,C标准库函数也调用系统调用,对吗? 但是为了在不同的操作系统中获得相同的输出,它可能必须调用不同的系统调用,对吗? 这是否意味着,即使是相同的标准C函数,系统调用 每个操作系统的内部实现不同


我真的想要一个关于系统调用的好概念(plz:)

我只知道一点关于Linux内核的知识,所以我将在回答中以Linux内核为例。要理解系统调用,您必须理解内核空间和用户空间的概念。系统调用是用户空间应用程序与内核通信的接口。因此,系统调用的实现是内核的一部分

首先,Linux内核大部分是用C编写的,部分是用汇编语言编写的。但是Linux内核从未使用任何C标准库函数。因此,在Linux中,用C标准库函数实现系统调用是不可能的

其次,Linux提供数百个系统调用。其中有些是用C语言编写的,但有些是用汇编语言实现的。不仅用C编写的程序可以进行系统调用,大多数其他语言如Ruby、Golang也可以这样做。恕我直言,说系统调用是用C编写的是不正确的


第三,不同的操作系统提供不同的系统调用集。即使相同的操作系统也可以运行在不同的体系结构中,如x86、arm等。不同的体系结构意味着不同的指令集。因此,即使相同的操作系统也可以以不同的方式实现相同的系统调用。因此,我认为您对这一点的理解是正确的。

系统调用是底层操作系统公开的功能。语言通常有一种定义良好的方式来发出系统调用。例如,英特尔x86处理器使用的是
syscall
指令,但您也可以使用其他方式,如发出中断指令

当进行系统调用时,会从用户空间转换到内核空间,内核空间以更高的特权级别运行。系统调用的参数被复制到内核空间并进行验证,以确保它们不会损害内核。但是,这些参数很可能也是用户空间中的验证。在某些情况下,用户空间函数将是内核函数的薄包装,而在其他情况下,它们将提供额外的特性

C和Unix有着紧密的传统,这就是为什么许多系统调用名与它们的C版本(例如fork、execXXX)相同的原因。然而,这只是一个惯例,并非所有地方都如此。在Windows上,系统调用的名称与Linux完全不同。但是,平台上的底层C运行时实现对您隐藏了这一点,并进行正确的系统调用以实现C函数提供的功能


通常,像Ruby这样的高级语言不会直接发出系统调用。相反,他们使用的是用低级语言(如C或C++)编写的库,将Ruby调用转换为对底层系统函数的调用。

系统调用和包装函数是两个不同的概念

  • 系统调用: 这些是内核空间中的正常函数。用户程序不能直接访问它们,即像你我这样的人编写的函数。系统调用只能由内核代码访问。这些功能将与设备或主存交互,以向用户程序提供请求的服务

  • 包装函数: 当您想在用户代码中使用系统调用时,您不能用用户空间中的函数直接调用它。处理器需要执行陷阱机器指令(中断)才能切换到内核模式。一旦切换到内核模式以执行系统函数,传递给该函数的参数中应该没有错误。系统调用不会检查其参数的正确性,所以如果参数有任何错误,则可能导致内核错误。如果您的用户空间程序出现故障,内核将终止您的进程,但是当内核出现故障时,您的整个内核都会崩溃,这是不可接受的。 包装函数确保所有参数都有效。如果一切正常,它们还设置了一个基址来捕获内核

  • 现在回答您的问题:

  • 包装器函数不执行系统调用函数,它们只检查参数的正确性,并通过传递适当的系统调用号将陷阱设置为内核模式。内核包含一个系统调用表(按编号),并执行请求的函数。一旦包装器函数调用了陷阱,它的工作就结束了

  • 包装函数是用C语言编写的常规用户级程序,部分用汇编语言编写。是的,包装函数可以调用标准库函数

  • 标准库函数是用C89、C99版本以及旧版本的C编写的。这并不重要,因为新版本的C是向后兼容的