在UNIX环境第2版,第01章,第11节中的高级编程中,有一句话:
例如,printf函数可以使用write系统调用来输出字符串, 但是strcpy(复制字符串)和atoi(将ASCII转换为整数)函数没有 完全涉及内核。
我不明白的是,为什么有可能根本没有内核的参与。并非所有例程都需要内核支持吗?
另外,我可能会发现atoi
只需要CPU计算。但是由于strcpy
需要内存操作,为什么它也不涉及内核支持?
通常,我如何识别函数不涉及内核?
答案 0 :(得分:5)
这似乎意味着该函数不会通过从该句子的上下文中说“不涉及内核”来导致系统调用。
答案 1 :(得分:3)
我不明白的是,为什么有可能根本没有内核的参与。并非所有例程都需要内核支持吗?
在非常最低级别,是的,因为如果没有内核启动它就不会存在进程,但这并不意味着每个操作都涉及内核。没有你的父母,你就不会存在,但这并不意味着你不能在没有父母参与的情况下穿上衣服。
如果你在C中编写一个简单的函数来解释它的参数,这是一个例程,它不需要内核的支持:
int func(int* p) { return *p; }
某些库函数(例如atoi
和strcpy
)是这样的,它们不会调用任何系统调用来使用内核提供的服务。
另外,我可能会发现
atoi
只需要CPU计算。但是由于strcpy
需要内存操作,为什么它也不涉及内核支持?
内核不用于在同一地址空间内将字节从一个位置复制到另一个位置。虚拟内存子系统可能涉及非常低的级别,将虚拟地址映射到物理地址,但对于几乎每个操作都是如此,即使(如果它不在寄存器中)读取或设置值也是如此一个int
!
无论如何,atoi
必须读取内存,为什么不考虑“需要内存操作”?
通常,我如何识别函数不涉及内核?
一般情况下,如果没有阅读该函数的来源,则无法进行。但是,如果一个函数可以在纯C中实现,而不与内核提供的硬件或服务交互(例如分支新进程或与其他进程通信),那么很可能它不使用系统调用。一些操作系统提供了找出进程使用的系统调用的方法,例如, strace
实用程序,它会在进程调用系统调用时告诉您。您也可以通过插入来跟踪进程或拦截系统调用,但这非常复杂,并且超出了此答案的范围。