我希望在运行于BSD操作系统的进程中实现一种有效的C文件复制技术。目前,该功能是使用读写技术实现的。我正在尝试通过使用内存映射文件复制技术来优化它。
基本上,我将分叉一个进程,mmap源文件和目标文件,并从源到目标执行指定字节的memcpy()。memcpy()返回后,该进程退出。这里需要使用msync()吗?因为当我实际调用带有MS_SYNC标志的msync()函数时,该函数需要很长时间才能返回。使用MS_ASYNC标志时也会出现相同的行为吗?
i)总结一下,避免使用msync()是否安全?
ii)在BSD中是否有更好的文件复制方式?因为BSD似乎不支持sendfile()或splice()。有其他等效方法吗?
iii)是否有简单的方法实现自己的零拷贝技术以满足此要求?
我的代码
/* mmcopy.c
Copy the contents of one file to another file, using memory mappings.
Usage mmcopy source-file dest-file
*/
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "tlpi_hdr.h"
int
main(int argc, char *argv[])
{
char *src, *dst;
int fdSrc, fdDst;
struct stat sb;
if (argc != 3)
usageErr("%s source-file dest-file\n", argv[0]);
fdSrc = open(argv[1], O_RDONLY);
if (fdSrc == -1)
errExit("open");
/* Use fstat() to obtain size of file: we use this to specify the
size of the two mappings */
if (fstat(fdSrc, &sb) == -1)
errExit("fstat");
/* Handle zero-length file specially, since specifying a size of
zero to mmap() will fail with the error EINVAL */
if (sb.st_size == 0)
exit(EXIT_SUCCESS);
src = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fdSrc, 0);
if (src == MAP_FAILED)
errExit("mmap");
fdDst = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fdDst == -1)
errExit("open");
if (ftruncate(fdDst, sb.st_size) == -1)
errExit("ftruncate");
dst = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdDst, 0);
if (dst == MAP_FAILED)
errExit("mmap");
memcpy(dst, src, sb.st_size); /* Copy bytes between mappings */
if (msync(dst, sb.st_size, MS_SYNC) == -1)
errExit("msync");
enter code here
exit(EXIT_SUCCESS);
}
msync(2)
,则需要注意。在您执行munmap(2)
文件之前,无法保证您的更改已经被刷新回文件系统。 - Witiko