利用标准库容器封装char,实现自动增长的缓冲区
缓冲区的自动增长的实现原理
web服务器之缓冲区的自动增长的实现原理
socket通信中的分散读和集中写
分散读示例
在Linux下,readv系统调用可以实现分散读(scattered read),即从一个文件描述符中读取数据到多个缓冲区中。下面是一个使用readv的C++示例,演示了如何从文件中分散读取数据:
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <vector>
#include <sys/uio.h>
int main() {
// 打开文件
int fd = open("example.txt", O_RDONLY); // 文件内容:hello,world
if (fd == -1) {
std::cerr << "Failed to open file" << std::endl;
return 1;
}
// 定义要读取的缓冲区
/* Structure for scatter/gather I/O. */
/*
struct iovec
{
void *iov_base; // Pointer to data.
size_t iov_len; // Length of data.
};
*/
std::vector<struct iovec> buffers;
buffers.emplace_back();
buffers.back().iov_base = (char*)malloc(5);
buffers.back().iov_len = 5;
buffers.emplace_back();
buffers.back().iov_base = (char*)malloc(1);
buffers.back().iov_len = 1;
buffers.emplace_back();
buffers.back().iov_base = (char*)malloc(5);
buffers.back().iov_len = 5;
// 读取数据
ssize_t bytesRead = readv(fd, buffers.data(), buffers.size());
if (bytesRead == -1) {
std::cerr << "Failed to read data" << std::endl;
close(fd);
return 1;
}
std::cout << "bytesRead = " << bytesRead << std::endl;
// 输出读取的数据
for (const auto& buffer : buffers) {
std::cout.write((char*)buffer.iov_base, buffer.iov_len) << std::endl;
}
// 释放缓冲区并关闭文件
for (auto& buffer : buffers) {
free((char*)buffer.iov_base);
}
close(fd);
return 0;
}
/*
输出:
bytesRead = 11
hello
,
world
*/
这段代码主要演示了如何使用 readv
函数从文件中进行分散读取,也就是从一个文件中读取数据到多个缓冲区中。下面是对这段代码的详细解释:
-
头文件引入
<iostream>
: 用于C++标准输入输出。<fcntl.h>
和<unistd.h>
: 这两个头文件包含了文件操作(如open
和close
)和低级I/O操作(如readv
)的函数声明。<vector>
: C++标准库中的动态数组。<sys/uio.h>
: 包含iovec
结构的定义,这个结构用于readv
和writev
函数的分散/聚集I/O。
-
主函数
-
打开文件:使用
open
函数打开名为 "example.txt" 的文件,并设置其为只读模式。如果文件打开失败,程序将输出错误消息并返回1。 -
定义要读取的缓冲区:使用
std::vector
来存储多个iovec
结构。每个iovec
结构代表一个缓冲区,其中iov_base
是指向数据的指针,iov_len
是数据的长度。- 第一个缓冲区大小为5,用于存储 "hello" 中的前5个字符。
- 第二个缓冲区大小为1,用于存储逗号 ","。
- 第三个缓冲区大小为5,用于存储 "world" 中的5个字符。
-
读取数据:使用
readv
函数从文件中读取数据。这个函数将从文件描述符fd
指向的文件中读取数据,并将数据分散到buffers
向量中的多个缓冲区中。readv
返回实际读取的字节数。如果读取失败,程序将输出错误消息,关闭文件并返回1。 -
输出读取的数据:遍历
buffers
向量,并使用std::cout.write
函数将每个缓冲区中的数据输出到标准输出。 -
释放缓冲区并关闭文件:在输出数据后,使用
free
函数释放每个缓冲区分配的内存,并使用close
函数关闭文件。
-
-
输出
- 输出实际读取的字节数,即11。
- 接着输出从文件中读取的内容,即 "hello\n,\nworld\n"。每个缓冲区的内容后面都有一个换行符,这是因为
std::cout.write
函数不会自动添加换行符,所以在每次写入后都需要手动添加。
Do not communicate by sharing memory; instead, share memory by communicating.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了