在我们产品的新版本中, 为了减少在嵌入式设备上的空间占用, 决定不再一开始就产生一系列大大的文件来存储将要用到的所有的共享资源(共享配置, 锁, 缓存等), 而是一开始产生一些很小的文件, 而后当需要更多资源的时候, 扩充文件.
由于共享资源都是存入文件而mmap进入进程空间的(默认模式), 要做到能够动态扩充被mmap的文件, 首先需要OS的支持, 即OS能够把mmap后被扩充的文件部分也mmap进来, 而无需关闭并重新打开文件.
然而, 在Cygwin上运行程序时, 我发现Cygwin并不支持我们所需要的特性:
int test_mmap4(){
const char *io_file = "tmp_mmap4_f";
int fid = 0, i = 0, ret = 0, cnt = 0;
void *addr1 = NULL;
int open_flags = 0, mode = 0, total_size = 0;
char buf[256], *caddr1 = NULL;
unlink(io_file);
open_flags = O_CREAT | O_TRUNC | O_RDWR;
mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
fid = open(io_file, open_flags, mode);
total_size = 1024 * 1024;
/* Write the first 64K bytes */
for(i = 0; i < 256; i++) {
memset(buf, 0, sizeof(buf));
lseek(fid, i * 256, SEEK_SET);
cnt = write(fid, buf, sizeof(buf));
}
/* mmap the file */
addr1 = mmap(NULL, total_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fid, 0);
/* Extend the file, write the last byte */
lseek(fid, total_size - 1, SEEK_SET);
cnt = write(fid, buf, sizeof(buf[0]));
caddr1 = (char *)addr1;
for(i = 0; i < total_size; i++) {
*** buf[0] = caddr1[i];
caddr1[i] = 'A';
}
ret = munmap(addr1, total_size);
ret = fsync(fid);
ret = close(fid);
return ret;
}
在测试程序***行执行到i=65536(64K)时, 程序崩溃. 经过测试, 我发现在Cygwin上的mmap存在64K边界的问题.
当一个文件被mmap进进程空间后, Cygwin允许动态扩充文件, 但是动态扩充的范围非常有限, 即不越过64K的边界. 换句话说, 能够访问的最大长度是, >=mmap时文件大小的最接近的64K的倍数.
由于这个限制的存在,我们也只能在Cygwin上关闭了这个新功能.
阅读(1100) | 评论(0) | 转发(0) |