关于库函数和系统调用的区别

zhqyzhqychn 2009-02-20 05:36:14
书上说;若干个库函数可以映射到一个系统调用入口点,比如exec有几种不同的调用方式,如execl 和execle,它们为同一系统调用提供不同接口。对于这些系统调用,它们的库函数对它们各自的参数加以处理,但最终的,这些库函数都映射到一个内核入口点。那到底什么是系统调用,什么是库函数。写程序时用的execl是系统调用还是库函数。这里面的库函数和C语言所说的库函数(如printf)有什么区别?我原以为像printf这样的称之为库函数而像creat,execl这样都叫做系统调用,好像这样理解不太正确,还有操作系统API又怎么界定,他属于系统调用还是系统调用的包装。
...全文
3965 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Felven 2012-03-18
  • 打赏
  • 举报
回复
学习了,南大面试题啊
sdau_computer 2010-08-31
  • 打赏
  • 举报
回复
虽然是一年前的帖子 不过既然看到了 我还是想发表一下我的意见。
应用程序有两种方式使用系统调用(以read为例):
1经过库函数向内核发出一个中断调用int 0x80时,就开始执行一个系统调用,函数定义为:
int read(int fd, char *buf, int n);
2在用户程序中直接执行对应的系统调用,该系统调用的宏的形式为:
define __LIBRARY__
#include <unistd.h>
_syscall3(int, read, int, fd, char *, buf, int, n)。
从第一种方式可以看出,楼主所说的exec应该是库函数,就像五楼所说的“很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用”。实际上,C函数库中函数最终调用系统调用的形式和第二种是一样的。
参见http://book.51cto.com/art/200812/103342.htm
wo81070279 2010-07-12
  • 打赏
  • 举报
回复
感觉很是深奥,现在还不懂
csdlinux 2010-06-17
  • 打赏
  • 举报
回复
我觉得是这样的
1.高级语言库函数的确是调用系统调用来实现的,所以说系统调用才是真正对硬件操作的。
但是大家可能注意到了为什么库函数为什么是通用的(同名),这是正是高级语言不依赖与特定的硬件。
其实,都是编译器来负责库函数到系统调用之间的转换的。比如说VC可能通过把fopen()对应到windows的打印系统调用XXX(不知道具体是哪个)上去了,而linux的编译器gcc通过把fopen()对应到linux的系统调用open上去了。
2.系统调用没有库函数的效率高是因为与设置的缓冲池大小有关吧,缓冲池(不知是用户的还是内核的)小的话,系统调用的操作就频繁,缓冲池(不知是用户的还是内核)大的的话,库函数就调用系统调用的次数就少。
3.应用程序可以直接调用库函数来操作。那么linux的源代码C里是不应该使用库函数的吧,你想。编译连接成内核镜像后,安装在裸机上,连个运行环境都没怎么系统调用啊。有的人会说,系统调用在编译连接的时候已经把系统调用弄进去了,那么不是说现在流行的动态连接吗,直到运行需要时才去连接吗。
最后,不知我的看法大家有没有意见喇。有的话,说出来大家讨论撒
mzmbushatan 2010-06-17
  • 打赏
  • 举报
回复
写得好
csdlinux 2010-06-17
  • 打赏
  • 举报
回复
我来说两句吧
fenbushi2010 2010-06-06
  • 打赏
  • 举报
回复

看完后 很有启发谢谢各位
correct 2009-03-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fetag 的回复:]
这个问题是这样的:

1. 首先,现在的OS内核主要采用两种模式,整体的单内核模式(linux)和分层的微内核模式(Windows)。单内核

模式的特点就是代码紧凑,执行速度快,各个模块之间是直接的调用关系,可以说最后一点既是优点,也是缺

点...有点就是执行速度快,缺点是内核看起来很乱,维护起来困难。

2. 无论是单内核,还是微内核,立体的体系结构从下到上大概都是分成这样几层:物理硬件,OS内核,OS服务,

应用程序…
[/Quote]
系统提供的api借口为什么就不需内核参与实现了呢?内核的下一层不就是硬件了么?
独孤过儿 2009-02-21
  • 打赏
  • 举报
回复
谢谢楼上大牛的谅解了!

能整天挂在CSDN上的人,也算是同病相怜了,别为小事不愉快哈,不值得,呵呵。大家都和和气气的,心情好点

,多美好的事啊,是不?O(∩_∩)O哈哈~
快乐田伯光 2009-02-21
  • 打赏
  • 举报
回复
没有这个意思,完全是就事论事, 如果你把最后的执行中断当成系统调用的定义,那我也没什么好说的了.

[Quote=引用 10 楼 fetag 的回复:]
呵呵,九楼的星星大牛就是看我这个小菜鸟不爽啊,O(∩_∩)O哈哈~,玩笑玩笑...

五楼兄弟这句话说的很对!佩服一下!

很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用

read()函数的执行过程是这样的:调用read()函数时,库函数首先保存read系统调用号以及参数(压入栈中),然

后执行0x80号中断,至此为止,库函数的工作就完成了。接下来就是执…
[/Quote]
独孤过儿 2009-02-21
  • 打赏
  • 举报
回复
呵呵,九楼的星星大牛就是看我这个小菜鸟不爽啊,O(∩_∩)O哈哈~,玩笑玩笑...

五楼兄弟这句话说的很对!佩服一下!

很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用

read()函数的执行过程是这样的:调用read()函数时,库函数首先保存read系统调用号以及参数(压入栈中),然

后执行0x80号中断,至此为止,库函数的工作就完成了。接下来就是执行系统调用了。
yangch_nhcmo 2009-02-21
  • 打赏
  • 举报
回复
学习
zhshto886 2009-02-21
  • 打赏
  • 举报
回复
UP!
快乐田伯光 2009-02-20
  • 打赏
  • 举报
回复
read引用的头文件是unistd.h 你再去看一下C标准库是都有哪些头文件.
自然read不可能直接对应一堆的汇编代码,但通常来说它就是一个系统调用, APUE里也是这么定义的.

[Quote=引用 8 楼 fetag 的回复:]
引用 6 楼 guosha 的回复:
很多C库函数名跟系统调用的函数名一样?
举几个例子试试看?
引用 5 楼 shicarl 的回复:
很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用
例如:
我自己定义一个系统调用sys_mycall,这个只能内核态调用,要在用户态编程使用时,需用函数_syscallN(N表示需要传给系统调用的参数个数)宏来将其声明,这样在我们自己的程序…
[/Quote]
独孤过儿 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 guosha 的回复:]
很多C库函数名跟系统调用的函数名一样?
举几个例子试试看?
引用 5 楼 shicarl 的回复:
很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用
例如:
我自己定义一个系统调用sys_mycall,这个只能内核态调用,要在用户态编程使用时,需用函数_syscallN(N表示需要传给系统调用的参数个数)宏来将其声明,这样在我们自己的程序中就可以使用mycall函数了

[/Quote]
你去man一下read看看,通常直接调用的read()是libc里面的库函数,而不是系统调用!
mymtom 2009-02-20
  • 打赏
  • 举报
回复
系统调用时用户进程进入内核的入口点
比如write就是系统调用。
对Unix来说,系统调用通常以C函数的方式提供了系统调用的C语言接口。
部分标准C函数使用了系统调用,如printf最终进行输出时用到了write系统调用。
部分标准C函数不使用系统调用,如strlen, strcat, memcpy等等。


快乐田伯光 2009-02-20
  • 打赏
  • 举报
回复
很多C库函数名跟系统调用的函数名一样?
举几个例子试试看?
[Quote=引用 5 楼 shicarl 的回复:]
很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用
例如:
我自己定义一个系统调用sys_mycall,这个只能内核态调用,要在用户态编程使用时,需用函数_syscallN(N表示需要传给系统调用的参数个数)宏来将其声明,这样在我们自己的程序中就可以使用mycall函数了

写程序直接使用的是库函数,而库函数内部可能就是调用的同名系统调用,这样是否好理解一点…
[/Quote]
水手carl 2009-02-20
  • 打赏
  • 举报
回复
很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用
例如:
我自己定义一个系统调用sys_mycall,这个只能内核态调用,要在用户态编程使用时,需用函数_syscallN(N表示需要传给系统调用的参数个数)宏来将其声明,这样在我们自己的程序中就可以使用mycall函数了

写程序直接使用的是库函数,而库函数内部可能就是调用的同名系统调用,这样是否好理解一点?
快乐田伯光 2009-02-20
  • 打赏
  • 举报
回复
read就是系统调用,而fread就是C标准库函数.
[Quote=引用 3 楼 fetag 的回复:]
这个问题是这样的:

1. 首先,现在的OS内核主要采用两种模式,整体的单内核模式(linux)和分层的微内核模式(Windows)。单内核

模式的特点就是代码紧凑,执行速度快,各个模块之间是直接的调用关系,可以说最后一点既是优点,也是缺

点...有点就是执行速度快,缺点是内核看起来很乱,维护起来困难。

2. 无论是单内核,还是微内核,立体的体系结构从下到上大概都是分成这样几层:物理硬件,OS内核,OS服务,

应…
[/Quote]
独孤过儿 2009-02-20
  • 打赏
  • 举报
回复
这个问题是这样的:

1. 首先,现在的OS内核主要采用两种模式,整体的单内核模式(linux)和分层的微内核模式(Windows)。单内核

模式的特点就是代码紧凑,执行速度快,各个模块之间是直接的调用关系,可以说最后一点既是优点,也是缺

点...有点就是执行速度快,缺点是内核看起来很乱,维护起来困难。

2. 无论是单内核,还是微内核,立体的体系结构从下到上大概都是分成这样几层:物理硬件,OS内核,OS服务,

应用程序。这四层结构中,OS内核起到一个“承上启下”的作用,向下管理物理硬件;向上为OS服务和应用程序

提供接口。主意,这里的接口实际上是指系统调用(System Call)。

3. 通常OS内核为了考虑实现起来的难度和易于管理,只提供少部分必要的系统调用,这些系统调用通常都是C和

汇编混编来实现的。接口用C定义,实现体用汇编来写。这样做的好处是,执行效率高,并且极大的方便了上层的

调用。

4. 再说库函数(即API)。库函数可以概括的分为两类,一类是随OS提供的,另一类是第三方的。随系统提供的库

函数进一步封装或组合系统调用,实现更多的功能,就像用C语言的许多功能单一的小函数来实现很多很多个功能

复杂的大函数一样。这样的API能够执行一些相对内核来说很复杂的操作,比如,read()函数根据参数,直接就

能读文件,而背后隐藏的比如文件在硬盘的哪个磁道,哪个扇区,加载到内存的哪个位置等等这些操作,程序员

是不必关心的,这些操作里面自然也包含了系统调用。而对于第三方的库,它其实和系统库一样,只是它直接利

用系统调用的可能性要小一些,而是利用系统提供的API接口来实现功能。(API的接口是开放的)

大概就这么多吧,想到哪写到哪,组织的也很凌乱,希望对楼主有帮助...
加载更多回复(2)

23,126

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧