我正在使用boost :: asio编写Http服务器。对于大文件,为了避免将整个文件读入内存并将其发送到网络,我逐个读取它,我使用boost :: asio :: async_write在网络上发送。
问题是我的生产者(从文件读取的函数)比消费者(boost :: asio :: async_write)快得多,这导致大文件的大量内存消耗。
我想通过限制缓冲区列表来避免这个问题。这似乎是一个简单的生产者/消费者问题,但是,我不想在这样做时阻止一个线程。
我使用boost :: io_service和一个n个线程的线程池,这是可配置的,如果我们对大文件有太多请求,我不想让服务器不再服务于任何请求。
所以我的问题是: - 如何在不阻塞线程的情况下设计此机制? - 我应该测试列表大小,如果它已经太大,会产生一个截止时间计时器,它将执行io_service :: post并继续读取我的文件吗? - 有更好的方法来解决这个问题吗?
答案 0 :(得分:0)
要防止出现此问题,您必须关心这两种资源。有许多算法可以限制分配的资源量。对于内存,您可以使用环形缓冲区来读取数据块。您还可以使用原子计数器来跟踪分配的资源量并建立上限。信号量也可用于解决此类问题。我更喜欢最后一个。伪代码看起来像这样。
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连接也是一种有限的资源。