库函数&系统调用函数
一、概念
系统调用(system call):系统调用实际上是指底层上的一个调用,就是内核提供的功能十分强大的一些函数。系统调用是在内核实现的,是操作系统为在用户态运行的进程和硬件设备进行交互提供的一组接口,就是设置在应用程序和硬件设备的接口层。由于系统调用不考虑平台差异性,由内核直接提供,因而移植性较差(几乎无移植性)。
库函数(library function):是用户或组织自己开发的具有一定功能的函数集合,一般具有较好平台移植性,通过库文件向程序员提供功能性调用。程序员无需关心平台差异,由库来屏蔽平台差异性。
二、区别
库函数 | 系统调用函数 |
---|---|
使用函数库中的一段程序 | 调用系统内核的服务 |
在用户空间执行 | 在内核空间执行 |
在所有版本编辑器中,C库函数是相同的 | 各个操作系统的调用不同 |
运行时间属于“用户时间” | 运行时间属于“系统时间” |
属于过程调用,开销较小 | 在用户空间和内核空间中切换,开销较大 |
是一个普通功能函数的调用 | 是操作系统的一个入口点 |
在C库中大约有300多个程序 | 在UNIX中大约有90多个系统调用 |
三、联系
实际上,库函数是对系统调用的一层封装,因此在用库函数对文件操作的时候,必然会引起系统调用。也就是说,库函数调用实际上是通过系统调用实现的,例如:C库函数fwrite()就是通过write实现的。系统调用其实是为了方便使用操作系统的接口,而库函数则是为了人们编程的方便。但是库函数在调用的时候有函数调用开销,而系统调用比库函数调用还要慢的多,因为它需要把上下文环境切换到内核模式。
问题:既然使用库函数调用也有系统调用的开销,那为什么不直接使用系统调用呢?
这是因为,读写文件通常是大量的数据,使用库函数调用可以大大减少系统调用的次数,由于在用户空间和内核空间,对文件操作都使用了缓冲区,当内核缓冲区写满之后或写结束之后才将内核缓冲区内容写到文件对应的硬件媒介中。