Linux线程池实现目录拷贝,linux多线程---使用mmap映射实现文件拷贝

一、代码实现思路

1、示意图

751575e11d6c12c09c99de4ed8277e23.png

2、示意图注解

循环创建i个线程,将src文件分为i段拷贝到dest文件中

(1)src文件的大小为src_size,前i-1个线程拷贝的文件大小为src_size/(i-1),第i个线程拷贝的文件大小为src_size%(i-1)

(2)线程i的文件偏移量=i*(src_size(i-1)),线程i的文件拷贝位置=起始位置+线程i的文件偏移量

二、使用mmap映射---多线程拷贝代码

#include

#include

#include

#include

#include

#include

#include

#include

#define PTHREAD_NUM 5 //线程数

struct CopyInfo{

char* src;

char* dest;

int num;

int src_size;

};

int main(int argc,char *argv[])

{

if(argc!=3){

printf("please input correct parameters\n");

return -1;

}

//1、打开文件src,dest

int fd_src=open(argv[1],O_RDONLY);

int fd_dest=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664);

//2、使用fstat获取文件src的大小,truncate拓展文件dest的大小

struct stat buf;

fstat(fd_src,&buf);

int src_size=buf.st_size;

truncate(argv[2],src_size);

//3、mmap创建文件src,dest的映射,判断映射返回值,关闭文件描述符

char* mmap_src=mmap(NULL,src_size,PROT_READ,MAP_PRIVATE,fd_src,0);

char* mmap_dest=mmap(NULL,src_size,PROT_WRITE,MAP_SHARED,fd_dest,0);

if(mmap_src==MAP_FAILED||mmap_dest==MAP_FAILED){

perror("mmap err");

return -1;

}

printf("src_size=%d\n",src_size);

close(fd_src);

close(fd_dest);

//4、对文件src的大小分段,循环创建线程,编写线程函数

pthread_t tid[PTHREAD_NUM];

struct CopyInfo copyInfos[PTHREAD_NUM];//创建PTHREAD_NUM个结构体

void* pthread_copy(void *CoIn);

for(int i=0;i

{

copyInfos[i].src=mmap_src;//可以改进的地方

copyInfos[i].dest=mmap_dest;//每个结构体的src、dest、src_size大小一样,可以写在一个结构体中

copyInfos[i].num=i; //可以将num单独写在一个结构体中,然后创建结构体数组

copyInfos[i].src_size=src_size;

pthread_create(&tid[i],NULL,pthread_copy,(void*)&copyInfos[i]);

}

//5、循环销毁线程,关闭mmap映射

for(int i=0;i

{

pthread_join(tid[i],NULL);

}

munmap(mmap_src,src_size);

munmap(mmap_dest,src_size);

return 0;

}

void* pthread_copy(void *CopyInfo)

{

struct CopyInfo* CoIn=(struct CopyInfo*)CopyInfo;

int par_lseek=CoIn->num*(CoIn->src_size/(PTHREAD_NUM-1));//par_lseek分段偏移量,计算出每段拷贝线程的距离文件起始位置的偏移量

printf("i=%d lseek=%d\n",CoIn->num,par_lseek);

if(CoIn->num

{

int copy_size=CoIn->src_size/(PTHREAD_NUM-1);

memcpy(CoIn->dest+par_lseek,CoIn->src+par_lseek,copy_size);//CoIn->dest+par_lseek:dest文件的起始位置+分段偏移量

}else //copyInfo->num==(PTHREAD_NUM-1)

{

int copy_size=CoIn->src_size%(PTHREAD_NUM-1);

memcpy(CoIn->dest+par_lseek,CoIn->src+par_lseek,copy_size);

}

//memcpy(CoIn->dest+par_lseek,CoIn->src+par_lseek,copy_size); //可以在此处内存拷贝

return NULL;

}

三、运行截图

73c94bded940fba30df2d2a492d4f337.png

注意事项:

gcc 01_mmap_pthread_copy.c -lpthread    多线程代码编译要加-lpthread,否则会报错

gcc对.c文件直接编译后,会生成a.out的可执行文件

一入编程深似海,多学多查多动手

#include#include#include#include#include#include#include#include

#define PTHREAD_NUM 5  //线程数

struct CopyInfo{    char* src;    char* dest;    int num;    int src_size;};

标签:src,include,CoIn,dest,mmap,linux,多线程,size

来源: https://www.cnblogs.com/asdzy/p/14296076.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值