b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

unix内核 《Linux高性能服务器编程》学习总结(六)——高级I/O函数

电脑杂谈  发布时间:2018-02-03 04:03:30  来源:网络整理

unix内核_unix内核源码剖析_linux最新内核版本

网络I/O一直是Linux网络编程中极其重要的一部分,除了前面讲到的send、recv等,socket编程接口还给出了很多高级了I/O函数,这些函数大致分为三类:用于创建文件描述符的函数、用于读写控制的函数和用于控制I/O行为和属性的函数。

pipe函数是用来创建一个管道,管道是较为原始的进程间通信手段,分为无名管道和有名管道,而无名管道只能用于有亲缘关系的进程之间传递消息。unix内核pipe建立的管道是单工的,其参数是一个包含两个元素的整形数组fd[2],创建成功后fd[0]代表管道可读的一端,fd[1]代表可写的一端,这两个的本质都是文件描述符,当进程间有数据要传输时,数据发送的一端需要关闭fd[0],接收端要关闭fd[1],才能正常传送数据。需要注意的是无名管道只能用低级文件编程库中的读写函数进行操作,如read和write,当我们向一个空管道执行read时,函数会阻塞,直到有数据写入才继续执行,同理对满的管道执行write也会进入阻塞状态。但是如果对于这两个文件描述符设置为非阻塞模式,则他们会有不同的行为。如果fd[1]的引用计数减少至0,即没有写端进程向管道中写,则fd[0]上的read操作将会读取到EOF标志,返回0;反之如果fd[0]上的引用计数减少至0,即没有读端程序调用read,则此时fd[1]上的write操作将失败并引发SIGPIPE信号。为了便于使用,API中还有一个函数用来创建双向管道,是socketpair函数,使用这个函数创建的双向管道只能使用AF_UNIX协议,即UNIX本地域协议族,它创建的两个文件描述符是既可读又可写的。

dup函数和dup2函数用于复制文件描述符,区别在于dup函数是将一个文件描述符复制到当前系统可用的最小整数值,而dup2则是不小于其参数的最小整数值,注意,通过这两个函数复制的文件描述符不继承其原来的属性。我们来看一个CGI服务器的例子:

技术分享图片

使用telnet客户端连接服务器发现有abcd的回显,通过这个例子我们可以看到,我们关闭了标准输出文件描述符后再调用dup,会将要复制的connfd复制到当前未使用的最小的文件描述符也就是标准输出文件描述符上,实现了输出的重定向。

readv和writev函数和前面提过的readmsg和writemsg函数类似,也是用来对数据的集中写和分散读,相当于前面两个函数的简化版。举一个例子来说明,在Web服务器解析完HTTP请求后如果客户端请求的文件存在并且有权限时,就需要返回一个HTTP首部状态码和状态信息,然后再返回该文件,但是我们考虑效率问题,如果每次我们都需要将两个不相关的存储空间合并到一起再发送势必会很影响效率,所以我们可以事先将HTTP不同的头部存储好,找到文件后使用sendv函数直接发送即可。我们建立一个test.txt文件模拟一下,服务器代码如下:

linux最新内核版本_unix内核_unix内核源码剖析

技术分享图片

使用telnet连接连接服务器端,发现正常回显了HTTP首部和数据。

接下来还有一个较为常用的函数sendfile,它的作用是在两个文件描述符之间直接传递数据,是一个零拷贝函数。所谓零拷贝函数,首先要知道内核空间和用户空间的概念和区别。Linux操作系统的内核使用了内存中的低地址区域,这里是我们在编程时不能访问的,很多缓冲区都是在这里定义,而用户空间就是其余的内存空间,我们在编写程序时可以进行操作。平时我们调用recv函数会将网络I/O数据拷贝到定义的用户缓冲区内,这样就会在内核空间和用户空间之间进行数据拷贝,这样就会导致进程再内核态和用户态之间进行频繁转换,降低效率。而零拷贝函数可以直接在内核态完成数据的传递,效率较高。unix内核其函数原型如下:


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-64695-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...