看系统调用,还有库函数,以前一直不明白,总是以为 系统调用跟库函数是一样的,但是今天才知道是不一样的。
库函数也就是我们通常所说的应用编程接口API,它其实就是一个函数定义,比如常见read()、write()等函数说明了如何获得一个给定的服务,但是系统调用是通过软中断向内核发出一个明确的请求,再者系统调用是在内核完成的,而用户态的函数是在函数库完成的。
系统调用发生在内核空间,因此如果在用户空间的一般应用程序中使用系统调用来进行文件操作,会有用户空间到内核空间切换的开销。事实上,即使在用户空间使用库函数来对文件进行操作,因为文件总是存在于存储介质上,因此不管是读写操作,都是对硬件(存储器)的操作,都必然会引起系统调用。也就是说,库函数对文件的操作实际上是通过系统调用来实现的。例如C库函数fwrite()就是通过write()系统调用来实现的。
这样的话,使用库函数也有系统调用的开销,为什么不直接使用系统调用呢?这是因为,读写文件通常是大量的数据(这种大量是相对于底层驱动的系统调用所实现的数据操作单位而言),这时,使用库函数就可以大大减少系统调用的次数。这一结果又缘于缓冲区技术。在用户空间和内核空间,对文件操作都使用了缓冲区,例如用fwrite写文件,都是先将内容写到用户空间缓冲区,当用户空间缓冲区满或者写操作结束时,才将用户缓冲区的内容写到内核缓冲区,同样的道理,当内核缓冲区满或写结束时才将内核缓冲区内容写到文件对应的硬件媒介。
系统调用与系统命令:系统命令相对API更高一层,每个系统命令都是一个可执行程序,比如常用的系统命令ls、hostname等,比如strace ls就会发现他们调用了诸如open(),brk(),fstat(),ioctl()等系统调用。
系统调用是用户进程进入内核的接口层,它本身并非内核函数,但他是由内核函数实现的,进入系统内核后,不同的系统调用会找到各自对应的内核函数,这写内核函数被称为系统调用的“服务例程”。也可以说系统调用是服务例程的封装例程。
阅读(4147) | 评论(0) | 转发(7) |