系统调用与库函数的异同

本文,探究系统调用和库函数调用的异同。(以文件操作为例,详情参考)


Linux 系统调用和 ANSI C文件操作的区别


我们知道在 Linux 下对文件操作有两种方式: Linux系统调用和ANSI C文件操作。 

Linux 系统调用指最底层的一个调用,在linux程序设计里面就是底层调用, 面向的是硬件。

ANSI C 是库函数调用,面向的是应用开发的,相当于应用程序的程序的API(应用程序接口)。


采用这样的方式有很多种原因: 

第一, 双缓冲技术的实现; 

第二,可移植性的考虑; 

三,底层调用本身的一些性能缺陷(如频繁擦写影响文件存储介质的寿命); 

第四, 让 API也可以有具体分层和专门的应用方向。


Linux 系统调用


Linux系统调用是操作系统相关的,因此一般没有跨操作系统的可移植性。Linux系统调用发生在内核空间,因此如果在用户空间的一般应用程序中使用系统调用来进行文件操作,会有用户空间到内核空间切换的开销。


事实上,即使在用户空间使用 ANSIC文件操作,因为文件总是存在于存储介质上,因此不管是读写操作,都是对硬件(存储器)的操作,都必然会引起Linux系统调用。

也就是说, ANSI C 文件操作实际上是通过系统调用来实现的。例如C库函数 fwrite()就是通过write()系统调用来实现的。


这样的话,使用库函数也有系统调用的开销,为什么不直接使用系统调用呢?

因为读写文件通常是大量的数据(这种大量是相对于底层驱动的系统调用所实现的数据操作单位而言)


这时,使用 ANSI C 文件操作就可以大大减少系统调用的次数。

这一结果又缘于缓冲区技术。


在用户空间和内核空间,对文件操作都使用了缓冲区,例如用 fwrite写文件,都是先将内容写到用户空间缓冲区,当用户空间缓冲区满或者写操作结束时,才将用户缓冲区的内容写到内核缓冲区。

同样的道理,当内核缓冲区满或写结束时才将内核缓冲区内容写到文件对应的硬件媒介。


ANSI C 文件操作

ANSI C文件操作通常用于应用程序中对一般文件的访问。

ANSI C 文件操作是系统无关的,因此可移植性好, 由于ANSI C文件操作是基于 C 的,因此也就不可能用于内核空间的驱动程序中对设备的操作。


你可能感兴趣的:(Linux,C/C++,点滴中的linux)