《TCP/IP详解 卷2:实现》 —1.6 系统调用和库函数

举报
华章计算机 发表于 2019/11/20 15:42:18 2019/11/20
【摘要】 本节书摘来自华章计算机《TCP/IP详解 卷2:实现》一书中第1章,第1.6节,作者是[美]加里R.赖特(Gary R.Wright),W. 理查德史蒂文斯(W.Richard Stevens),陆雪莹 蒋慧 等译 谢希仁 校。

1.6   系统调用和库函数

所有的操作系统都提供服务访问点,程序可以通过它们请求内核中的服务。各种Unix都提供精心定义的有限个内核入口点,即系统调用。我们不能改变系统调用,除非我们有内核的源代码。Unix第7版提供了大约50个系统调用,4.4BSD提供了大约135个,而SVR4大约有120个。

在《Unix程序员手册》第2节中有系统调用接口的文档。它是以C语言定义的,在任何给定的系统中无须考虑系统调用是如何被调用的。

在各种Unix系统中,每个系统调用在标准C函数库中都有一个相同名字的函数。一个应用程序用标准C的调用序列来调用此函数。这个函数再调用相应的内核服务,所使用的技术依赖于所在系统。例如,函数可能把一个或多个C参数放到通用寄存器中,并执行几条机器指令产生一个软件中断进入内核。对于我们来说,可以把系统调用看成C函数。

在《Unix程序员手册》的第3节中为程序员定义了一般用途的函数。虽然这些函数可能调用一个或多个内核系统调用,但没有进入内核的入口点。如函数printf可能调用了系统调用write去执行输出,而函数strcpy(复制一个串)和atoi(将ASCII码转换成整数)完全不涉及操作系统。

从实现者的角度来看,系统调用和库函数有着根本的区别,但在用户看来区别并不大。例如,在4.4BSD中我们运行图1-2中的程序。程序调用了3个函数—socket、sendto和recvfrom,每个函数最终调用了内核中一个同样名称的函数。在本书的后面我们可以看到这3个系统调用的BSD内核实现。

如果我们在SVR4中运行这个程序,在那里,用户库中的插口函数调用“流”子系统,那么3个函数同内核的相互作用是完全不同的。在SVR4中对socket的调用最终会调用内核的   open系统调用,操作文件/dev/udp并将流模块sockmod放置到结果流。调用sendto导致一个putmsg系统调用,而调用recvfrom导致一个getmsg系统调用。这些SVR4的细节在本书中并不重要,我们仅仅想指出的是:实现可能不同但都提供相同的API给应用程序。

最后,从一个版本到下一个版本的实现技术可能会改变。例如,在Net/1中,send和sendto是分别用内核系统调用实现的。但在Net/3中,send是一个调用系统调用sendto的库函数:

send(int s, char *msg, int len, int flags)

{

    return(sendto(s, msg, len, flags, (struct sockaddr *) NULL, 0));

}

用库函数实现send的好处是仅调用sendto,减少了系统调用的个数和内核代码的长度;缺点是由于多调用了一个函数,增加了进程调用send的开销。

因为本书是说明TCP/IP的伯克利实现,所以大多数进程调用的函数(socket、bind、connect等)是直接由内核系统调用来实现的。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。