1、系统调用是最底层的调用,是面向硬件的;而库函数的调用是面向开发的,相当于应用程序的 API 接口。
2、各个操作系统的系统调用是不同的,因此系统调用没有跨操作系统的可移植性;而库函数的可移植性良好。
3、库函数属于过程调用,调用开销小;系统调用需要在用户空间和内核态之间切换,调用开销大。
4、有时候库函数调用函数库中的一段程序,这段程序最终还是要通过系统调用来完成、实现,系统调用调用的是系统内核的服务。
比如对于文件的操作,由于文件是存储在介质上的,所以读写都是对硬件(存储器)的操作,所以肯定会引起系统调用;C中的 fopen() 库函数封装了系统调用的很多细节,但还是通过系统调用 open() 来实现的。
5、即使使用库函数也会有系统调用的情况,但是由于缓冲区技术,可以减少系统调用的次数,提高程序的运行效率;比如对于文件操作,在内核空间和用户空间,都使用了缓冲区,都先将内容写到用户空间缓冲区,当用户空间缓冲去写满或者写操作结束时,才将用户缓冲区的内容写到内核缓冲区,当内核缓冲区写满或者写结束时才将内核缓冲区的内容写到文件对应的硬件媒介上。
系统调用的具体过程:
如图,当应用程序调用系统调用时,会先查到系统调用号,之后产生0x80 中断,将系统调用号放入寄存器,此时从用户态切换到内核态,根据系统调用号在系统调用表中查,查到后通过内核方法实现,将结果返回给寄存器,最终返回给应用程序