Linux系统编程学习之《论使用mmap复制文件》
来源:互联网 发布:mac上安装ipad应用 编辑:程序博客网 时间:2024/05/22 11:35
由于想加速今天使用了mmap来写一个复制文件的程序,发现原来使用mmap来复制文件原来是不够直接用read和write来复制文件快的
也许有人会觉得我不对,不过我首先说明复制背景:
我的复制文件不像《UNIX网络编程卷2》上面说的那样,有一个客户端和一个服务端进程,我的只有一个进程,在这一个进程内进行复制操作。
首先列出一下我写的两个复制文件的函数:
使用mmap复制的函数:
static int copyfile(const char * source, const char * destination, int mode) {int fd_r, fd_w;struct stat file_stat;ssize_t file_len;char *file_buf_r, *file_buf_w;if (0 == mode) {mode = 0660;}fd_r = open(source, O_RDONLY);if (fd_r < 0) {return 1;}if (fstat(fd_r, &file_stat) < 0) {close(fd_r);return 1;}file_len = file_stat.st_size;file_buf_r = (char *) mmap(NULL, file_len, PROT_READ, MAP_SHARED, fd_r,SEEK_SET);if (file_buf_r == MAP_FAILED) {close(fd_r);return 1;}close(fd_r);fd_w = open(destination, O_CREAT | O_RDWR, mode);if (fd_w < 0) {close(fd_r);munmap(file_buf_r, file_len);return 1;}if (ftruncate(fd_w, file_len) < 0) {close(fd_w);munmap(file_buf_r,file_len);unlink(destination);return 1;}file_buf_w = (char *) mmap(NULL, file_len, PROT_WRITE, MAP_SHARED, fd_w,SEEK_SET);if (file_buf_w == MAP_FAILED) {close(fd_w);munmap(file_buf_r, file_len);unlink(destination);return 1;}close(fd_w);if (NULL == memcpy(file_buf_w, file_buf_r, file_len)) {munmap(file_buf_r, file_len);munmap(file_buf_w, file_len);unlink(destination);return 1;}if (msync(file_buf_w, file_len, MS_SYNC) < 0) {munmap(file_buf_r, file_len);munmap(file_buf_w, file_len);unlink(destination);return 1;}munmap(file_buf_r, file_len);munmap(file_buf_w, file_len);return 0;}
接着贴上我使用read和write复制文件的函数代码:
static int copyfile(const char * source,const char * destination,int mode){int srcfd,desfd;int exit_status;off_t filelen;ssize_t nwrite,n;exit_status = 0;srcfd = -1;desfd = -1;char * buf[BUFFSIZE];if (NULL == source || NULL == destination) {exit_status = 1;goto exit_program;}if (0 == mode) {mode = 0660;}if (access(source,F_OK) < 0) {exit_status = 1;goto exit_program;}if ( (srcfd = open(source,O_RDONLY)) < 0 ) {exit_status = 1;goto exit_program;}if (creat(destination,mode) < 0) {exit_status = 1;goto exit_program;}if ((desfd = open(destination,O_WRONLY,O_APPEND)) < 0) {exit_status = 1;goto exit_program;}filelen = lseek(srcfd,0,SEEK_END);lseek(desfd,0,SEEK_SET);nwrite = 0;while (nwrite < filelen) {n = pread(srcfd,buf,BUFFSIZE,nwrite);if (n < 0) {exit_status = 1;goto exit_program;}n = write(desfd,buf,n);if (n < 0) {exit_status = 1;goto exit_program;}nwrite += n;}exit_status = 0;exit_program:if (srcfd >= 0) {close(srcfd);}if (desfd >= 0) {if (1 == exit_status) {unlink(destination);}close(desfd);}return exit_status;}
看这两个函数的代码数量相差不大,但是性能却有所差异
原本我以为使用mmap会使得复制更快,但是结果却是read和write组合复制文件更快些
经过我多次测试,测试复制100个图片文件
使用mmap的函数使用大概2.5s
而使用read和write的函数使用大概2.3s
虽然只有0.2s的差距,但是如果文件数量一大,那么这个差距就显示出来了
我这里并不是说mmap没有用处,本来mmap的定位都是用于进程间共享内存的
所以如果对于复制文件这样没有共享内存的操作,mmap失去了优势,反而可能成为劣势,不如read和write
但是如果是两个进程间通信,如果用read和write对管道(FIFO等)进行数据读写,那么效率肯定是不如直接使用mmap高效
- Linux系统编程学习之《论使用mmap复制文件》
- 使用mmap复制文件
- Linux系统编程(5)——文件与IO之mmap函数
- linux系统编程学习day5--IPC之共享内存(通过mmap实现)
- linux系统编程 - 文件复制程序
- Linux文件系统编程 系统调用 文件复制
- linux c之mmap使用
- mmap() 实现文件复制
- linux系统编程:进程间通信-mmap
- linux 编程之文件内容复制
- linux编程初探之 实现文件复制
- linux编程初探之 实现文件复制
- linux 使用系统接口实现复制文件
- 使用mmap即文件映射实现文件的快速复制
- Linux内存管理之mmap详解 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,
- linux编程学习笔记(九) 获取文件状态与文件映射mmap
- linux编程学习6-文件操作之用open、read、write实现文件复制拷贝功能
- Linux系统编程学习之《文件和目录操作》
- Import Error: No module named yaml
- 海量查询的数据优化
- c++ this指针
- js中一个函数获取另一个函数返回值问题
- 实现android按下回车键便隐藏输入键盘
- Linux系统编程学习之《论使用mmap复制文件》
- android wifi
- Godaddy 优惠券 优惠码 持续更新
- 浅谈list-style
- 【玩转Ubuntu】09. Ubuntu上安装apktool
- 交付给事业多少,你就能成就多少事业
- Android开发经验之点击图片判断是否在图片范围之内
- POJ:1679 The Unique MST(判断最小生成树是否唯一)
- 论文