繁体   English   中英

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

[英]What's the difference between “C system calls” and “C library routines”?

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

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

例如,有getmntinfo(3)getfsstat(2) ,看起来他们都做同样的事情。 什么时候应该使用哪个和有什么区别?

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

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

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

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

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

在此输入图像描述

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

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

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

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

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

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

  1. 你想成为libc不可知论者; 也许安装人员。 无论使用何种库,此类代码都可以在Android( 仿生 ), uClibc和更传统的glibc / eglibc系统上运行。 此外,动态加载包装器,使运行时glibc /仿生层允许双Android / Linux二进制。
  2. 你需要极端的表现。 虽然这可能很少见,但很可能是错误的。 可能重新思考这个问题会带来更好的性能优势,而不是调用系统往往是性能上的胜利,而libc偶尔会这样做。
  3. 您正在编写一些没有库的initramfsinit代码; 创建更小的图像或更快地启动。
  4. 您正在测试新的内核/平台,并且不希望使用完整的文件系统使生活复杂化; initramfs非常相似。
  5. 您希望在程序启动时快速执行某些操作,但最终还是希望使用libc例程。
  6. 避免libc的已知错误。
  7. libc无法使用该功能。

对不起,大多数示例都是特定于Linux的,但理由应该适用于其他Unix变体。 当新功能引入内核时,最后一项很常见。 例如,当首次引入kqueueepoll ,没有libc来支持它们。 如果系统具有较旧的库,但是较新的内核并且您希望使用此功能,则也可能发生这种情况。

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

其他答案已经在libc和系统调用之间的区别上做了一个很好的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM