Linux高性能服务器编程——高级I/O函数



高级I/O函数

pipe函数

pipe函数用于创建一个管道,实现进程间的通信。

#include <unistd.h>

int pipe(int pipefd[2]);

通过pipe函数创建的文件描述符fd[0]和fd[1]分别构成管道的两端,往fd[1]写入的数据可以从fd[0]读出,不能反过来。管道内部传输的数据时字节流,和TCP字节流概念相同,但有区别,管道本身拥有一个容量限制,它规定如果应用程序不将数据从管道读走的话,该管道最多能被写入多少字节的数据。管道容量阿东小默认是65536字节,可以用fcntl函数来修改管道容量。

此外,socket基础API中有一个socketpair函数,能够方便创建双向管道。

#include<sys/types.h>         /* See NOTES*/

#include<sys/socket.h>

intsocketpair(int domain, int type, int protocol, int sv[2]);

这里domain只能使用UNIX本地域协议族AF_UNIX,因为我们仅能在本地使用这个双向管道。

dup函数和dup2函数

#include <unistd.h>

int dup(int oldfd);

int dup2(int oldfd, int newfd);

dup函数创建一个新的文件描述符,该新的文件描述符和原有的文件描述符file_descriptor指向相同的文件、管道或网络连接。并且dup返回的文件描述符总是取系统当前可用的最小整数值。Dup2和dup类型,不过它将返回第一个不小于newfd的整数值。dup和dup2系统调用失败时返回-1并设置errno。

通过dup和dup2创建的文件描述符并不继承原文件描述符的属性。

readv函数和writev函数

readv函数将数据从文件描述符督导分散的内存块中,即分散读。Writev函数则将多块分散的内存数据一并写入文件描述符中,即集中写。定义如下:

#include <sys/uio.h>

ssize_t readv(int fd, const struct iovec*iov, int iovcnt);

ssize_t writev(int fd, const struct iovec*iov, int iovcnt);

fd是文件描述符,iov是iovec结构数组,该结构体描述一块内存区,iovcnt参数是数组的长度。

sendfile函数

sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了内核缓冲区和用户缓冲区之间的数据拷贝,效率高,这被称为零拷贝。

#include <sys/sendfile.h>

ssize_t sendfile(int out_fd, int in_fd,off_t *offset, size_t count);

in_fd参数是带读出内容的文件描述符,out_fd参数是带写入内容的文件描述符,offset参数指定从读入文件流的哪个位置开始读,count指定文件描述符in_fd和out_fd之间传输的字节数。

mmap函数和munmap函数

mmap函数用于申请一段内存空间。我们可以将这段内存作为进程通信的共享内存,也可以将文件直接映射到其中。Munmap函数则释放由mmap创建的这段内存空间。定义如下:

#include <sys/mman.h>

void *mmap(void *addr, size_t length, intprot, int flags, int fd, off_t offset);

int munmap(void *addr, size_t length);

其中,start参数允许用于使用某个特定的地址作为这段内存的起始地址。如果被设置成NULL,则系统自动分配一个地址。Length参数指定内存段的长度。Port参数用来设置内存段的访问权限,flag参数控制内存段被修改后程序的行为。Fd参数是被映射文件对应的文件描述符。Mmap函数成功时返回指向目标内存区域的指针,失败则返回MAP_FAILED,并设置errno。

splice函数

#include <fcntl.h>

ssize_t splice(int fd_in, loff_t *off_in,int fd_out, loff_t *off_out, size_t len, unsigned int flags);

用来控制两个文件描述符之间的数据移动,也是零拷贝操作。Flag参数控制数据流如何移动。

tee函数

tee函数在两个管道文件描述符之间复制数据,也是零拷贝操作。它不消耗数据,因此源文件描述符上的数据仍然可以用于后续的读操作。Tee函数的原型如下:

#define _GNU_SOURCE        /* See feature_test_macros(7) */

#include <fcntl.h>

ssize_t tee(int fd_in, int fd_out, size_tlen, unsigned int flags);

fcntl函数

fcntl函数提供了对文件描述符的各种控制操作。另外一个常见的控制文件描述符属性和行为的系统调用时ioctl,而且ioctl比fcntl能够执行更多的控制。

Linux高性能服务器编程——高级I/O函数

时间: 2024-10-12 03:37:12

Linux高性能服务器编程——高级I/O函数的相关文章

Linux 高性能服务器编程——高级I/O函数

重定向dup和dup2函数 [cpp] view plaincopyprint? #include <unistd.h> int dup(int file_descriptor); int dup2(int file_descriptor_one, int file_descriptor_two); dup创建一个新的文件描述符, 此描述符和原有的file_descriptor指向相同的文件.管道或者网络连接. dup返回的文件描述符总是取系统当前可用的最小整数值. dup2函数通过使用参数f

Linux高性能server编程——高级I/O函数

 高级I/O函数 pipe函数 pipe函数用于创建一个管道,实现进程间的通信. #include <unistd.h> int pipe(int pipefd[2]); 通过pipe函数创建的文件描写叙述符fd[0]和fd[1]分别构成管道的两端,往fd[1]写入的数据能够从fd[0]读出,不能反过来.管道内部传输的数据时字节流,和TCP字节流概念同样,但有差别,管道本身拥有一个容量限制,它规定假设应用程序不将数据从管道读走的话,该管道最多能被写入多少字节的数据.管道容量阿东小默认是65

Linux 高性能server编程——高级I/O函数

重定向dup和dup2函数 #include <unistd.h> int dup(int file_descriptor); int dup2(int file_descriptor_one, int file_descriptor_two); dup创建一个新的文件描写叙述符, 此描写叙述符和原有的file_descriptor指向同样的文件.管道或者网络连接. dup返回的文件描写叙述符总是取系统当前可用的最小整数值. dup2函数通过使用參数file_descriptor_two指定新

linux高性能服务器编程

<Linux高性能服务器编程>:当当网.亚马逊 目录: 第一章:tcp/ip协议族 第二章:ip协议族 第三章:tcp协议详解 第四章:tcp/ip通信案例:访问Internet 第五章:linux网络编程基础API 第六章:高级IO函数 第七章:linux服务器程序规范 第八章:高性能服务器框架 第九章:IO复用 第十章:信号 第十一章:定时器 第十二章:高性能IO框架库libevent 第十三章:多进程编程 第十四章:多线程编程 第十五章:进程池和线程池 第十六章:服务器调制.调试和测试

Linux高性能服务器编程——定时器

 定时器 服务器程序通常管理着众多定时事件,因此有效组织这些定时事件,使之能在预期的时间点被触发且不影响服务器的主要逻辑,对于服务器的性能有着至关重要的影响.位置我们要将每个定时事件封装成定时器,并使用某种容器类型的数据结构,比如链表.排序链表和时间轮将所有定时器串联起来,以实现对定时事件的统一管理. Linux提供三种定时方法: 1.socket选项SO_RECVTIMEO和SO_SNDTIMEO. 2.SIGALRM信号 3.I/O复用系统调用的超时参数 socket选项SO_RCVTI

Linux高性能服务器编程——信号及应用

 信号 信号是由用户.系统或者进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常.Linux信号可由如下条件产生: 对于前台进程,用户可以通过输入特殊的终端字符来给它发送信号.比如输入Ctrl+C通常会给进程发送一个终端信号. 2.系统异常 系统状态变化 运行kill命令或调用kill函数 Linux信号概述 发送信号 Linux下,一个进程给其他进程发送信号的API是kill函数.其定义如下: #include <sys/types.h> #include <sign

Linux高性能服务器编程——多进程编程

多进程编程 多进程编程包括如下内容: 复制进程影映像的fork系统调用和替换进程映像的exec系列系统调用. 僵尸进程以及如何避免僵尸进程 进程间通信(Inter-Process Communication,IPC)最简单的方式:管道 3种进程间通信方式:信号量,消息队列和共享内存 fork系统调用 #include<unistd.h> pid_tfork(void); 该函数的每次都用都返回两次,在父进程中返回的是子进程的PID,在子进程中返回的是0.该返回值是后续代码判断当前进程是父进程还

Linux高性能服务器编程——进程池和线程池

进程池和线程池 池的概念 由于服务器的硬件资源"充裕",那么提高服务器性能的一个很直接的方法就是以空间换时间,即"浪费"服务器的硬件资源,以换取其运行效率.这就是池的概念.池是一组资源的集合,这组资源在服务器启动之初就完全被创建并初始化,这称为静态资源分配.当服务器进入正是运行阶段,即开始处理客户请求的时候,如果它需要相关的资源,就可以直接从池中获取,无需动态分配.很显然,直接从池中取得所需资源比动态分配资源的速度要快得多,因为分配系统资源的系统调用都是很耗时的.当

Linux高性能服务器编程——I/O复用

 IO复用 I/O复用使得程序能同时监听多个文件描述符,通常网络程序在下列情况下需要使用I/O复用技术: 客户端程序要同时处理多个socket 客户端程序要同时处理用户输入和网络连接 TCP服务器要同时处理监听socket和连接socket,这是I/O复用使用最多的场合 服务器要同时处理TCP请求和UDP请求.比如本章将要讨论的会社服务器 服务器要同时监听多个端口,或者处理多种服务. I/O复用虽然能同时监听多个文件描述符,但它本身是阻塞的.并且当多个文件描述符同时就绪时,如果不采用额外措施