简体   繁体   English

如何将缓冲区传递给write()而不为其分配内存

[英]How to pass a buffer to write() without allocating memory for it

It's hard to phrase the question, but I'll try. 这个问题很难说,但我会尽力的。 I want to test performance of my usb connection, therefor I'm using gadgetfs on an ambedded device so I can just do a write to a filedescriptor and the data is sent to the host. 我想测试USB连接的性能,因此,我在嵌入式设备上使用gadgetfs,因此我可以对文件描述符进行写操作,然后将数据发送到主机。 But when I want to send large amounts of data, I cannot allocate as much data as I want to. 但是,当我要发送大量数据时,我无法分配所需数量的数据。

write(int fildes, const void *buf, size_t nbyte);

Is there a way to pass a pointer to somewhere in memory where it can actually read nbyte Bytes? 有没有一种方法可以将指针传递到内存中可以实际读取nbyte Bytes的位置? I can't allocate an array or a vector of the size that I want to send. 我无法分配要发送的大小的数组或向量。 cause I get an "Cannot allocate memory" error. 原因我收到“无法分配内存”错误。

If your OS has MAP_ANONYMOUS or /dev/zero then you could mmap that into your virtual address space up to the maximum possible mapping and read from there. 如果你的操作系统有MAP_ANONYMOUS/dev/zero ,那么你可以mmap是到您的虚拟地址空间达到最大可能的映射,并从那里读取。

#include <sys/mman.h>

void * zeroed_memory = mmap(NULL, nbytes, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

This will allocate a continuous mapping of length nbytes to a single zeroed out read-only page and thus does not actually use any physical memory. 这会将长度为nbytes的连续映射分配给单个置零的只读页面,因此实际上不使用任何物理内存。 You can read the whole array (and will only get zeroes), but you can not write to it. 您可以读取整个数组(并且只会得到零),但是不能对其进行写入。

Most systems will limit your maximum continuous virtual mapping though due to physical hardware restrictions. 由于物理硬件限制,大多数系统都会限制最大连续虚拟映射。 Current x86_64 Linux generally supports 64TB long mappings. 当前的x86_64 Linux通常支持64TB长的映射。

Note: some systems (OS X for instance, maybe other BSD based have MAP_ANON instead of MAP_ANONYMOUS , consult man 2 mmap to find out the exact one). 注意:某些系统(例如OS X,也许其他基于BSD的系统具有MAP_ANON而不是MAP_ANONYMOUS ,请咨询man 2 mmap以找出确切的系统)。

If MAP_ANONYMOUS is not supported on your system, but /dev/zero is then an equivalent method is: 如果MAP_ANONYMOUS上不支持MAP_ANONYMOUS ,但是/dev/zero是等效的方法是:

void * zeroed_memory;
int fd = open("/dev/zero", O_RDONLY);
if (fd > 0) {
    zeroed_memory = mmap(NULL, nbytes, PROT_READ, MAP_PRIVATE, fd, 0);
}

The write function will take whatever address you give it, and (attempt to) write nbyte bytes from that address onwards. write函数将使用您提供的任何地址,并(尝试)从该地址开始写入nbyte字节。 As long as the memory is possible to read, this should work fine. 只要可以读取内存,它就可以正常工作。

If you want to send more than a few kilobytes, it is often better to do that as multiple writes of a relatively small size (say 4KB), and use a loop to complete the write. 如果您要发送几个千字节以上的数据,通常最好以相对较小的大小(例如4KB)进行多次写入,并使用循环来完成写入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM