#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
/// argv[1]: process num
/// argv[2]: file path
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("bad argv, need 3 arg\n");
return -1;
}
// filesize
struct stat sbuf;
int ret = stat(argv[2], &sbuf);
if (ret < 0) {
perror("stat");
return -1;
}
// filesize
off_t sz = sbuf.st_size;
off_t yu = sz % atoi(argv[1]);
// ever process
off_t proSz = (sz - yu) / atoi(argv[1]);
// open source file
int srcfd = open(argv[2], O_RDONLY);
// create target file
char wk[20] = {0};
sprintf(wk, "%s.copy", argv[2]);
int decfd = open(wk, O_RDWR | O_CREAT | O_TRUNC, 0766);
// change size
ret = ftruncate(decfd, sz);
if (ret < 0) {
perror("ftruncate");
return -1;
}
void *src = mmap(NULL, sz, PROT_READ, MAP_SHARED, srcfd, 0);
if (src == MAP_FAILED) {
perror("mmap src:");
return -1;
}
// des mmap
void *dst = mmap(NULL, sz, PROT_WRITE | PROT_READ, MAP_SHARED, decfd, 0);
if (dst == MAP_FAILED) {
perror("mmap dst:");
return -1;
}
int i;
int pCnt = atoi(argv[i]);
// create child pid
for (i = 0; i < pCnt; ++i) {
// in child process
if (fork() == 0)
break;
}
// in child process
//子进程的处理
if (i < pCnt) {
// last time
if (i == pCnt - 1) {
memcpy(dst + i * proSz, src + i * proSz, proSz + yu);
} else {
memcpy(dst + i * proSz, src + i * proSz, proSz);
}
}
//父进程的处理
else {
/// wait child pid
for (int i = 0; i < pCnt; ++i) {
wait(NULL);
}
// printf("parent pid=%d\n", getpid());
if (munmap(src, sz) == -1) {
perror("munmap src");
}
if (munmap(dst, sz) == -1) {
perror("munmap dsc");
}
close(srcfd);
close(decfd);
}
return 0;
}
网友评论