【问题标题】:Why some functions don't involve kernel?为什么有些功能不涉及内核?
【发布时间】:2013-10-29 14:50:20
【问题描述】:

Advanced Programming in the UNIX Environment 2nd Edition,第01章,第11节中有一句话:

例如 printf 函数可以使用 write 系统调用来输出一个字符串, 但是 strcpy (复制字符串)和 atoi (将 ASCII 转换为整数)函数没有 完全涉及内核。

我不明白的是,为什么可能根本没有内核参与。不是所有的例程都需要内核支持吗?

另外,我可能会发现atoi 只需要 CPU 计算。但是strcpy需要内存操作,为什么也不涉及内核支持呢?

一般来说,我如何才能识别出一个函数不涉及内核?

【问题讨论】:

  • 内核通常只在程序想要与自身外部通信或重新配置系统时参与。例如,访问已分配的内存往往不需要(显式)内核参与,但是如果无法从程序中已保存的池中满足新的内存分配,则可能需要。

标签: c linux linux-kernel system posix


【解决方案1】:

从那句话的上下文来看,这似乎意味着该函数不会通过说“不涉及内核”来导致系统调用。

【讨论】:

  • 那么涉及内核的意思是说这些系统调用在第2节?
  • 我手头没有那本书,所以不确定第 2 节是什么……但通常系统调用是用户程序与内核交互的方式。
【解决方案2】:

我不明白的是,为什么可能根本没有内核参与。不是所有的例程都需要内核支持吗?

非常最低级别,是的,因为如果没有内核启动一个进程甚至不存在,但这并不意味着内核参与每个操作。没有父母你就不会存在,但这并不意味着“没有父母的参与”你就不能穿衣服。

如果你用 C 编写一个简单的函数,它只是简单地取消引用它的参数,那就是一个例程,它不需要内核的支持:

int func(int* p) { return *p; }

一些库函数,比如atoistrcpy就是这样的,它们不会调用任何系统调用来使用内核提供的服务。

另外,我可能会发现atoi 只需要 CPU 计算。但是strcpy需要内存操作,为什么也不涉及内核支持呢?

内核不用于在同一地址空间内将字节从一个地方复制到另一个地方。虚拟内存子系统可能涉及非常低的级别,将虚拟地址映射到物理地址,但几乎每个操作都是如此,即使(如果它不在寄存器中)读取或设置值int!

反正atoi要读内存,你怎么不认为“需要内存操作”呢?

一般来说,我如何才能识别出一个函数不涉及内核?

一般情况下,如果不阅读函数的源代码,您就无法做到。但是,如果一个函数可以在纯 C 中实现,而不与内核提供的硬件或服务交互(例如派生新进程或与其他进程通信),那么它很可能不使用系统调用。一些操作系统提供了找出进程使用哪个系统调用的方法,例如strace 实用程序,它会在进程调用系统调用时告诉您。您还可以通过插入来跟踪进程或拦截系统调用,但这非常复杂,超出了此答案的范围。

【讨论】:

  • 感谢您的详细信息!所以如果我知道一个 C 函数不包含对系统调用的调用(在传递意义上)并且没有嵌入 ASM,那么它不涉及内核?
  • 是的。即使它包含嵌入式 ASM,它也可能不涉及内核,除非 ASM 使用系统调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 2021-02-26
  • 2017-12-23
相关资源
最近更新 更多