linux – 在将大数据写入套接字时最小化副本

前端之家收集整理的这篇文章主要介绍了linux – 在将大数据写入套接字时最小化副本前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写一个处理图像(大数据)的应用程序服务器.我正在尝试将图像数据发送回客户端时最小化副本.我需要发送给客户的处理过的图像是从jemalloc获得的缓冲区.我想到将数据发送回客户端的方法是:

1)简单的写呼叫.

// Allocate buffer buf.
// Store image data in this buffer.
write(socket,buf,len);

2)我通过mmap而不是jemalloc获取缓冲区,虽然我认为jemalloc已经使用mmap创建了缓冲区.然后我做一个简单的写电话.

buf = mmap(file,len);  // Imagine proper options.
// Store image data in this buffer.
write(socket,len);

3)我像以前一样通过mmap获取缓冲区.然后我使用sendfile发送数据:

buf = mmap(in_fd,len);  // Imagine proper options.
// Store image data in this buffer.
int rc;
rc = sendfile(out_fd,file,&offset,count);
// Deal with rc.

似乎(1)和(2)可能会做同样的事情,因为jemalloc可能首先通过mmap分配内存.但我不确定(3).这真的会带来什么好处吗?这个article on Linux零拷贝方法的图4表明使用sendfile可以防止进一步复制:

no data is copied into the socket buffer. Instead,only descriptors
with information about the whereabouts and length of the data are
appended to the socket buffer. The DMA engine passes data directly
from the kernel buffer to the protocol engine,thus eliminating the
remaining final copy.

如果一切顺利,这似乎是一场胜利.我不知道我的mmaped缓冲区是否算作内核缓冲区.另外我不知道什么时候重新使用这个缓冲区是安全的.由于fd和length是唯一附加到套接字缓冲区的东西,我假设内核实际上异步地将这些数据写入套接字.如果它执行sendfile的返回表示什么?我怎么知道什么时候重用这个缓冲区?

所以我的问题是:

>将大缓冲区(我的情况下的图像)写入套接字的最快方法是什么?图像保存在内存中.
>在mmapped文件调用sendfile是个好主意吗?如果是,那有什么问题?这甚至会带来任何胜利吗?

解决方法

似乎我的怀疑是正确的.我从 article获得了我的信息.引用它:

Also these network write system calls,including sendfile,might and
in many cases do return before the data sent over TCP by the method
call has been acknowledged. These methods return as soon as all data
is written into the socket buffers (sk buff) and is pushed to the TCP
write queue,the TCP engine can manage alone from that point on. In
other words at the time sendfile returns the last TCP send window is
not actually sent to the remote host but queued. In cases where
scatter-gather DMA is supported there is no seperate buffer which
holds these bytes,rather the buffers(sk buffs) just hold pointers to
the pages of OS buffer cache,where the contents of file is located.
This might lead to a race condition if we modify the content of the
file corresponding to the data in the last TCP send window as soon as
sendfile is returned. As a result TCP engine may send newly written
data to the remote host instead of what we originally intended to
send.

如果mmapped文件中的缓冲区甚至被认为是“DMA-able”,那么在没有来自实际客户端的显式确认(通过网络)的情况下,似乎无法知道何时重新使用它是安全的.我可能不得不坚持简单的写入调用并产生额外的副本.有一个paper(也来自文章)有更多细节.

编辑:此拼接调用上的article显示问题.引用它:

Be aware,when splicing data from a mmap’ed buffer to a network socket,it is not possible to say when all data has been sent. Even if splice() returns,the network stack may not have sent all data yet. So reusing the buffer may overwrite unsent data.

猜你在找的Linux相关文章