提升::async_write大文件和内存消耗
boost::async_write large files and memory consumption
我正在使用boost::asio编写一个Http服务器。对于大文件,为了避免将整个文件读入内存并将其发送到网络,我使用 boost::asio::async_write 在网络上发送的部分读取它。
问题是我的生产者(从文件中读取的函数)比消费者(boost::asio::async_write)快得多,这导致大文件的巨大内存消耗。
我想通过限制缓冲区列表来避免此问题。这似乎是一个简单的生产者/消费者问题,但是,我不想在这样做时阻止线程。
我将 boost::io_service 与可配置的 n 个线程的线程池一起使用,如果我们对大文件有太多请求,我不想最终导致服务器不再为任何请求提供服务。
所以我的问题是: - 如何在不阻塞线程的情况下设计此机制? - 我是否应该测试列表大小,然后如果它已经太大,生成一个截止日期计时器,它将执行 io_service::p ost 并继续读取我的文件? - 有没有更好的方法来处理这个问题?
如果你想防止dos攻击,阻塞读取线程不是一个好主意。您试图避免的是同时分配过多的资源(内存)。但是打开的文件流的数量也是有限的。如果在过载情况下开始阻塞读取线程,则可以非常快速地获得大量打开的文件流。如果您发现错误,您的程序可能不会崩溃,但这肯定是不希望的行为,因为您无法打开其他文件(例如.log文件)。
为了防止此问题,您必须照顾这两种资源。有许多算法可以限制分配的资源量。对于内存,您可以对读取数据块使用环形缓冲区。您还可以使用原子计数器来跟踪分配的资源量并建立上限。信号量也可用于解决此类问题。我更喜欢最后一个。伪代码看起来像这样。
Semaphore filestreams(maxNumberOfFilestreams);
Semaphore memory(maxNumberOfAllocatedChunks);
// Worker thread to read
void run() {
filestream.wait();
while(!eof) {
memory.wait();
// Allocate and read
}
file.close();
filestream.notify()
}
// Sending thread()
void run() {
while(true) {
// grab chunk, send and free memory
memory.notify();
}
}
请记住,开放的 tcp 连接也是有限的资源。
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- C/C++ - 查询平台相关的换行符(用于内存映射文件)
- WinVerifyTrust 仅在使用文件而不是内存 blob 时才有效
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- 在指向现有内存地址的 hpp 文件中声明成员函数的最佳方法
- 内存映射文件访问非常慢
- 我正在尝试创建一个C++映射,该映射在boost内存映射文件中具有向量值
- 这些结构在文件中的大小不同,但在程序内存中的大小相同
- 在嵌入式系统中读取文件的内存碎片
- 如何从文件中读取 100x24 矩阵并将其作为浮点矩阵保存在内存中?
- 测量任何 Windows 可执行文件的内存使用情况和执行时间
- 提升进程间共享内存删除、权限和输出文件
- 将内存文件添加到 clang 编译器实例
- 为什么我的 C++ 程序在执行 TCMALLOC 堆检查器或堆配置文件时使用大量内存
- C++ 从磁盘读取文件并将其写入共享内存
- 为什么在编译时需要知道对象的内存配置文件以进行堆栈放置?
- 增强共享内存:文件的卷已被外部更改,打开文件不再有效
- 在内存文件中使用
- 创建内存文件
- 将char指针映射到具有文件描述符的内存文件