学习系列:《APUE14.8》《CSAPP9.8.4》
gcc -o main1 -Wall -g -ggdb -O0 -g3 -gdwarf-2 main1.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define COPYINCR (1024 * 1024 * 1024) /* 1 GB */
int main(int argc, char *argv[])
{
int fdin, fdout;
void *src;
void *dst;
size_t copysz;
struct stat sbuf;
off_t fsz = 0;
if (argc != 3)
{
printf("usage: %s \n" , argv[0]);
exit(1);
}
if ((fdin = open(argv[1], O_RDONLY)) < 0)
{
printf("can't open %s for reading\n", argv[1]);
}
if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
{
printf("can't creat %s for writing\n", argv[2]);
}
if (fstat(fdin, &sbuf) < 0) /* need size of input file */
{
printf("fstat error\n");
}
if (ftruncate(fdout, sbuf.st_size) < 0) /* set output file size */
{
printf("ftruncate error\n");
}
while (fsz < sbuf.st_size)
{
if ((sbuf.st_size - fsz) > COPYINCR)
{
copysz = COPYINCR;
}
else
{
copysz = sbuf.st_size - fsz;
}
if ((src = mmap(0, copysz, PROT_READ, MAP_SHARED, fdin, fsz)) == MAP_FAILED)
{
printf("mmap error for input\n");
}
printf("src: %p\n", (char *)src);
if ((dst = mmap(0, copysz, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, fsz)) == MAP_FAILED)
{
printf("mmap error for output\n");
}
printf("dst: %p\n", (char *)src);
memcpy(dst, src, copysz); /* does the file copy */
munmap(src, copysz);
munmap(dst, copysz);
fsz += copysz;
}
exit(0);
}
// gcc -o main1 -Wall -g -ggdb -O0 -g3 -gdwarf-2 main1.c
执行结果:
[mingjie@centos ~/proj/mmap]$ gcc -o main1 -Wall -g -ggdb -O0 -g3 -gdwarf-2 main1.c
[mingjie@centos ~/proj/mmap]$ ./main1 a.data b.data
src: 0x7fde70798000
dst: 0x7fde70798000
[mingjie@centos ~/proj/mmap]$ cat a.data
aaaaaaaa
bbb
[mingjie@centos ~/proj/mmap]$ cat b.data
aaaaaaaa
bbb
// 定义:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
// 实例1中:
mmap(0, copysz, PROT_READ, MAP_SHARED, fdin, fsz)
mmap(0, copysz, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, fsz)
CreateAnonymousSegment
ptr = mmap(NULL, allocsize, PROT_READ | PROT_WRITE, PG_MMAP_FLAGS | mmap_flags, -1, 0);
效果:
匿名映射的优点:
匿名映射的缺点:
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
/*Pointer to shared memory region*/
int *addr;
addr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED)
{
fprintf(stderr, "mmap() failed\n");
exit(EXIT_FAILURE);
}
*addr = 1;
/*Parent and child share mapping*/
switch (fork())
{
case -1:
fprintf(stderr, "fork() failed\n");
exit(EXIT_FAILURE);
case 0:
/*Child: increment shared integer and exit*/
printf("Child started, value = %d, ++value\n", *addr);
(*addr)++;
if (munmap(addr, sizeof(int)) == -1)
{
fprintf(stderr, "munmap()() failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
default:
/*Parent: wait for child to terminate*/
if (wait(NULL) == -1)
{
fprintf(stderr, "wait() failed\n");
exit(EXIT_FAILURE);
}
printf("In parent, value = %d\n", *addr);
if (munmap(addr, sizeof(int)) == -1)
{
fprintf(stderr, "munmap()() failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
}
// gcc -o main3 -Wall -g -ggdb -O0 -g3 -gdwarf-2 main3.c
执行结果
[mingjie@centos ~/proj/mmap]$ ./main3
Child started, value = 1, ++value
In parent, value = 2