使用mmap實(shí)現(xiàn)多進(jìn)程對(duì)大文件拷貝
本文實(shí)例為大家分享了mmap實(shí)現(xiàn)文件多進(jìn)程拷貝,供大家參考,具體內(nèi)容如下
假設(shè)有一個(gè)超大文件,需對(duì)其完成拷貝工作。為提高效率,可采用多進(jìn)程并行拷貝的方法來(lái)實(shí)現(xiàn)。假設(shè)文件大小為len,共有n個(gè)進(jìn)程對(duì)該文件進(jìn)行拷貝。那每個(gè)進(jìn)程拷貝的字節(jié)數(shù)應(yīng)為len/n。但未必一定能整除,我們可以選擇讓最后一個(gè)進(jìn)程負(fù)責(zé)剩余部分拷貝工作。可使用len % (len/n)將剩余部分大小求出。
為降低實(shí)現(xiàn)復(fù)雜度,可選用mmap來(lái)實(shí)現(xiàn)源、目標(biāo)文件的映射,通過(guò)指針操作內(nèi)存地址,設(shè)置每個(gè)進(jìn)程拷貝的起始、結(jié)束位置。借助MAP_SHARED選項(xiàng)將內(nèi)存中所做的修改反映到物理磁盤(pán)上。
思路:
//1. 指定創(chuàng)建子進(jìn)程的個(gè)數(shù)
//2. 打開(kāi)源文件
//3. 打開(kāi)目的文件, 不存在則創(chuàng)建
//4. 獲取文件大小
//5. 根據(jù)文件大小拓展目標(biāo)文件
//6. 為源文件創(chuàng)建映射
//7. 為目標(biāo)文件創(chuàng)建映射
//8. 求出每個(gè)子進(jìn)程該拷貝的字節(jié)數(shù)
//9. 創(chuàng)建N個(gè)子進(jìn)程
//10. 子進(jìn)程完成分塊拷貝(注意最后一個(gè)子進(jìn)程拷貝起始位置)
//11. 釋放映射區(qū)
代碼如下:
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include<sys/wait.h>
#include<string.h>
#include <fcntl.h>
int main(int argc,char*argv[])
{
int n;
if(argc < 3 || argc > 4)
{
printf("Enter like this : ./a.out file_src file_dst [proc_number]\n");
exit(1);
}
else if(argc == 3) //用戶未指定,默認(rèn)創(chuàng)建5個(gè)進(jìn)程。
n = 5;
else
n = atoi(argv[3]);
//2.打開(kāi)源文件
int fd_src = open(argv[1],O_RDONLY);
if(fd_src < 0)
{
perror("open");
exit(2);
}
//3.打開(kāi)目標(biāo)文件,不存在就創(chuàng)建,存在則截?cái)酁?的大小。
int fd_dst = open(argv[2],O_RDWR |O_CREAT |O_TRUNC,0664);
if(fd_dst < 0)
{
perror("open");
exit(3);
}
//4.獲取源文件大小。
struct stat sbuf;
int ret = fstat(fd_src,&sbuf); //fd_src所指向的文件信息保存到結(jié)構(gòu)體sbuf中。
if(ret < 0)
{
perror("fstat");
exit(4);
}
int flen = sbuf.st_size; //源文件大小。
if(flen < n) //文件長(zhǎng)度小于進(jìn)程個(gè)數(shù)。
{
n = flen;
}
//5.根據(jù)文件大小拓展目標(biāo)文件。
ret = ftruncate(fd_dst,flen);//將參數(shù)fd指定的文件大小改為參數(shù)length指定的大小
if(ret < 0)
{
perror("ftruncate");
exit(5);
}
//6.為源文件創(chuàng)建映射。
// void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
//addr == NULL,表示內(nèi)核選擇一個(gè)合適的地址創(chuàng)建一個(gè)length大小的共享內(nèi)存,
char *mp_src = (char*)mmap(NULL,flen,PROT_READ,MAP_SHARED,fd_src,0); //0,表示將fd_src所指向的文件從起始映射到共享內(nèi)存中,共享內(nèi)存的權(quán)限為只讀,進(jìn)程間共享。
if(mp_src == MAP_FAILED) //mmap一定要檢查返回值。
{
perror("mmap");
exit(6);
}
close(fd_src);
//7.為目標(biāo)文件創(chuàng)建映射。
char *mp_dst = (char*)mmap(NULL,flen,PROT_READ|PROT_WRITE,MAP_SHARED,fd_dst,0);
if(mp_dst == MAP_FAILED) //mmap一定要檢查返回值。
{
perror("mmap");
exit(7);
}
close(fd_dst);
//8.求出每個(gè)進(jìn)程拷貝的字節(jié)數(shù)。
int bs = flen / n;
int mod = flen % bs; //求出均分后余下的字節(jié)數(shù),讓最后一個(gè)子進(jìn)程處理。
char *temp_src = mp_src;
char *temp_dst = mp_dst;
//9.創(chuàng)建n個(gè)子進(jìn)程。
int i ;
pid_t pid;
for(i = 0; i < n; ++i)
{
printf("create %dth proc\n",i);
if( (pid =fork()) == 0 )
break;
}
if(n == i) //父進(jìn)程。
{
int j = 0;
for(j = 0; j < n; ++j)
wait(NULL);
}
else if(i == (n-1)) //10.子進(jìn)程拷貝,最后一個(gè)子進(jìn)程,它多處理均分后剩下的字節(jié)數(shù)。
{
printf("i = %d\n",i);
memcpy(temp_dst+i*bs,temp_src+i*bs,bs+mod);
}
else if(i == 0)
{
printf("i = %d\n",i);
memcpy(temp_dst,temp_src,bs);
}
else
{
printf("i = %d\n",i);
memcpy(temp_dst+i*bs,temp_src+i*bs,bs);
}
//11.釋放映射區(qū)。
munmap(mp_src,flen);
munmap(mp_dst,flen);
return 0;
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:C++實(shí)現(xiàn)簡(jiǎn)單射擊小游戲
欄 目:C語(yǔ)言
下一篇:C++使用string的大數(shù)減法運(yùn)算(2)
本文標(biāo)題:使用mmap實(shí)現(xiàn)多進(jìn)程對(duì)大文件拷貝
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/184.html
您可能感興趣的文章
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-用棧實(shí)現(xiàn)表達(dá)式求值的方法詳解
- 01-10使用OpenGL實(shí)現(xiàn)3D立體顯示的程序代碼
- 01-10求斐波那契(Fibonacci)數(shù)列通項(xiàng)的七種實(shí)現(xiàn)方法
- 01-10C語(yǔ)言 解決不用+、-、&#215;、&#247;數(shù)字運(yùn)算符做加法
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10深入全排列算法及其實(shí)現(xiàn)方法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改


