96-Linux系统调用与库函数的区别

Linux系统调用与库函数的区别

库函数的实现是在用户空间,在函数的库里,我们自己也可以做出来,静态库,共享库,其实和我们自己在代码中实现一个方法去调用它,本质上没有什么区别,方法的实现都是用户自己完成。
但是系统调用的实现是在操作系统中,在编译操作系统的时候,就实现了该方法,所以用户是不可能去执行操作系统的代码,因此它的调用执行和库函数的调用执行是不一样的。
我们自己实现一个函数,那我们去调用这个函数,就是跳到函数入口进行往下执行。
但是系统调用就不一样,系统调用一旦执行,就要从用户空间切换到内核空间,表明上看,长得都和函数差不多,我们在虚拟地址层看看:

在这里插入图片描述
编号是3,就是库函数
在这里插入图片描述
编号为2,是系统调用,实现是在内核中
在这里插入图片描述
fork也是系统调用,在内核中实现。
凡是要对硬件或者操作系统底层做操作的话,就是系统调用。
有些功能,用户自己是做不了的,需要操作系统来做(磁盘写数据,操作文件)。

区别: 系统调用的实现在内核中,属于内核空间,库函数的实现在函数库中,属于用户空间

系统调用执行过程如下图:
在这里插入图片描述
系统调用号:在内核空间,对系统实现的方法进行编号,这个号是绝对的,从内核源码中摘抄出来的一部分,在内核中,有系统调用表:系统调用号和系统调用方法的入口地址组成,应用程序去执行open的时候,就会产生中断,当前的这个应用程序不能往下执行了,内核要上来处理这个中断,open执行以后,会将这个open对应的系统调用号5写到寄存器Eax中,接下来应用程序产生中断,应用程序就被换下去了,现场保护,把当前的应用程序在CPU中运行的各个寄存器上的信息存在内核栈上,内核上来执行,操作系统从Eax寄存器中把系统调用号5读出来,在系统调用表查,查出来是sys_open,然后找到它对应的实现方法,然后就去打开一个文件,在内核中会创建一些数据结构,来表征这个打开的文件,然后把open的返回值,也就是文件描述符写入到Eax寄存器中,相当于把刚才引发的中断处理完了,恢复应用程序的执行,恢复以后,首先第一时间从Eax寄存器把结果3读出来,赋给fd,然后应用程序继续向下执行。
内核代表用户在做打开文件的操作。
系统调用虽然效率很高,执行完之后去内核空间执行,但是,如果说频繁进行切换,切换的开销就比较大。
所以printf优化为先给缓冲区输入数据,
因为如果我们的printf要往屏幕上输入信息,最终调用的是write的系统调用,如果不添加缓冲区,执行一下printf,马上切换到内核态,执行一下write,把内容写到屏幕上,然后刚恢复到用户空间,可能马上又要执行printf,把数据往屏幕上写,又要产生中断,切换到内核态,执行write,把数据写到屏幕上,然后恢复到用户空间,让应用程序执行,频繁切换,效率变得, 所以我们就给printf一个缓冲区,当执行printf方法,把打印的信息写到缓冲区中,等缓冲区满了之后,再从用户空间切换到内核空间,把数据全部写到屏幕上,只切换1次!!!效率就高了!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值