手册页中有多个部分。其中两个是:
2 Unix 和 C 系统调用 3 C 程序的 C 库例程
getmntinfo(3)
和 getfsstat(2)
,两者看起来都做同样的事情。什么时候应该使用哪个以及有什么区别?
常用函数库构建在系统调用接口之上,但应用程序可以自由使用两者。
系统调用就像有权使用内核资源的身份验证密钥。
上图来自高级 Linux 编程,有助于理解用户应用程序如何与内核交互。
系统调用是用户级代码和内核之间的接口。 C 库例程是像任何其他库调用一样的库调用,它们只是碰巧被普遍提供(几乎普遍存在)。 许多标准库例程都是系统调用的包装器(瘦的或其他的),这确实会使界限有点模糊。
至于使用哪一种,一般来说,使用最适合您需求的一种。
手册第 2 节中描述的调用都是对捕获内核的系统服务的实际调用的相对较薄的包装。 本手册第 3 节中描述的 C 标准库例程是客户端库函数,它们实际上可能会也可能不会使用系统调用。
这篇文章描述了系统调用和捕获内核(在稍微不同的上下文中),并通过一些参考解释了系统调用背后的底层机制。
作为一般规则,您应该始终使用 C 库版本。 他们通常有包装器来处理深奥的事情,例如根据信号重新启动(如果您有要求)。 如果您已经与该库链接,则尤其如此。 所有规则都有被打破的理由。使用直接通话的原因,
libc
不可知论者;也许有安装程序。 此类代码可以在 Android (bionic)、uClibc 和更传统的 glibc/eglibc 系统上运行,无论使用什么库。 此外,使用包装器动态加载以创建运行时 glibc/bionic 层,允许双 Android/Linux 二进制文件。libc
偶尔可以做到这一点。initramfs
或 init
代码;创建更小的映像或更快地启动。initramfs
非常相似。libc
例程。libc
中的已知错误。libc
使用该功能。抱歉,大多数示例都是 Linux 特定的,但其原理应该适用于其他 Unix 变体。 当新功能引入内核时,最后一项非常常见。 例如,当
kqueue
或 epoll
首次引入时,没有 libc
支持它们。 如果系统有较旧的库,但有较新的内核并且您希望使用此功能,也可能会发生这种情况。
如果您的进程尚未使用
libc
,那么系统中很可能会有某些东西。 通过编写自己的变体,您可以通过提供通往同一最终目标的两条路径来取消缓存。 另外,Unix
将在进程之间共享代码页。 一般来说没有理由不使用libc
版本。
其他答案已经在
libc
和系统调用之间的差异方面做出了出色的工作。