linux多线程---使用mmap映射实现文件拷贝教程
一、代码实现思路
1、示意图
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映射---多线程拷贝代码
<pre class="brush:cpp;gutter:true;">#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<sys/mman.h>
#include<unistd.h>
#include<pthread.h>
#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<PTHREAD_NUM;++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*)©Infos[i]);
}
//5、循环销毁线程,关闭mmap映射
for(int i=0;i<PTHREAD_NUM;++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<(PTHREAD_NUM-1))
{
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;
}
三、运行截图
注意事项:
gcc 01\_mmap\_pthread\_copy.c -lpthread 多线程代码编译要加-lpthread,否则会报错
gcc对.c文件直接编译后,会生成a.out的可执行文件
一入编程深似海,多学多查多动手
\#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<string.h>#include<sys/mman.h>#include<unistd.h>#include<pthread.h>
\#define PTHREAD\_NUM 5 //线程数
struct CopyInfo{ char* src; char* dest; int num; int src\_size;};
当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »