“C系统调用”和“C库例程”之间有什么区别?

时间:2009-02-21 13:02:21

标签: c unix system man

联机帮助页中有多个部分。其中两个是:

2     Unix and C system calls
3     C Library routines for C programs

例如,有getmntinfo(3)getfsstat(2),两者看起来都是一样的。什么时候应该使用哪个,有什么区别?

5 个答案:

答案 0 :(得分:30)

系统调用是操作系统函数,就像在UNIX上一样,malloc()函数建立在sbrk()系统调用之上(用于调整进程内存空间)。

库只是不属于操作系统的应用程序代码,通常可以在多个操作系统上使用。它们与您自己程序中的函数调用基本相同。

该行可能有点模糊,但只是将系统调用视为内核级功能。

答案 1 :(得分:12)

系统调用是用户级代码和内核之间的接口。 C库例程就像其他任何库调用一样,它们恰好是真正普遍提供的(非常普遍)。许多标准库例程都是围绕系统调用的包装器(薄或其他),这确实会使线条模糊不清。

关于使用哪一个,作为一般规则,使用最适合您需要的那个。

答案 2 :(得分:12)

常用功能库建立在系统调用接口之上,但应用程序可以自由使用。

系统调用就像身份验证密钥,可以访问内核资源。

enter image description here

上图来自高级Linux编程,有助于了解用户应用与内核的交互方式。

答案 3 :(得分:6)

本手册第2节中描述的调用都是针对陷阱到内核的系统服务的实际调用的相对较薄的包装器。本手册第3节中描述的C标准库例程是客户端库函数,可能会也可能不会实际使用系统调用。

This posting描述了系统调用和对内核的捕获(在稍微不同的上下文中),并解释了系统调用背后的基本机制。

答案 4 :(得分:3)

作为一般规则,您应始终使用C库版本。他们经常使用包装器处理深奥的事情,比如重新启动信号(如果你已经要求的话)。如果您已经与库链接,则尤其如此。所有规则都有理由被打破。使用直接电话的原因,

  1. 你想成为libc不可知论者;也许安装人员。无论使用何种库,此类代码都可以在Android(bionic),uClibc和更传统的glibc / eglibc系统上运行。此外,动态加载包装器,使运行时glibc /仿生层允许双Android / Linux二进制文件。
  2. 你需要极端的表现。虽然这可能很少见,但很可能是错误的。可能重新考虑问题会带来更好的性能优势,并且调用系统往往是性能上的胜利,libc偶尔可以做到。
  3. 您正在编写一些没有库的initramfsinit代码;创建更小的图像或更快地启动。
  4. 您正在测试新的内核/平台,并且不希望使用完整的文件系统来复杂化生活;与initramfs非常相似。
  5. 您希望在程序启动时快速执行某些操作,但最终希望使用libc例程。
  6. 避免libc中的已知错误。
  7. libc无法使用该功能。
  8. 很抱歉,大多数示例都是针对Linux的,但理由应该适用于其他Unix变体。当新功能引入内核时,最后一项很常见。例如,在首次引入kqueueepoll时,没有libc来支持它们。如果系统具有较旧的库,但是较新的内核并且您希望使用此功能,则也可能发生这种情况。

    如果您的流程未使用libc,那么很可能系统中的某些内容会有。通过编码自己的变体,您可以通过提供到同一个最终目标的两条路径来否定缓存。还有,Unix 将在进程之间共享代码页。通常没有理由不使用libc版本。

    其他答案已经在libc和系统调用之间的差异方面做得非常出色。