多线程拷贝和多进程拷贝思路相同,只是把进程换成了线程,提高程序的并发性,代码如下:
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
typedef struct{
char *mm,*mm_1;
size_t size_num;
}node;
void *thread_copy(void *arg)//主控函数
{
node *content = (node *)arg;
//memcpy(content->mm_1,content->mm,content->size_num);
for(int i=0;i<content->size_num;i++)
{
*content->mm_1++ = *content->mm++;
}
free(content);
pthread_exit((void*)1);
}
int main(int argc,char *argv[])
{
if(argc < 4)
{
fprintf(stderr,"usage: %s argv[1] argv[2] argv[3]\n",argv[0]);
exit(1);
}
//获取文件的inode节点信息
struct stat statbuff;
int set = stat(argv[1],&statbuff);
//获得线程数量
int num = 0;
int len = strlen(argv[3]);
for(int i=0;i < len;i++)
{
num*=10;
num+=argv[3][i]-'0';
}
pthread_t tid[num];
int ret;
size_t size_num = statbuff.st_size/num;//每个线程需要拷贝的大小
size_t size_last = statbuff.st_size%num;//剩下的部分由最后一个线程负责
node content;//向线程传递拷贝的起始地址和大小的结构体
content.size_num = size_num;
int fd1 = open(argv[1],O_RDONLY);
if(fd1 == -1)
{
fprintf(stderr,"open %s error\n",argv[1]);
exit(1);
}
int fd2 = open(argv[2],O_RDWR | O_CREAT | O_TRUNC,0644);
ftruncate(fd2,statbuff.st_size);
if(fd2 == -1)
{
fprintf(stderr,"open %s error\n",argv[2]);
exit(1);
}
//建立mmap映射区
char *mm=mmap(NULL,statbuff.st_size,PROT_READ,MAP_SHARED,fd1,0);
if(mm == MAP_FAILED)
{
perror("mmap_fd1 error");
exit(1);
}
close(fd1);
char *mm1 = mmap(NULL,statbuff.st_size,PROT_WRITE,MAP_SHARED,fd2,0);
if(mm1 == MAP_FAILED)
{
perror("mm1_mmap error");
exit(1);
}
close(fd2);
//创建多个子线程
for(int i=0;i<num+1;i++)
{
content.mm = mm+size_num*i;
content.mm_1 = mm1+size_num*i;
if(i == num)
{
content.size_num = size_last;
}
node *p=(node *)malloc(sizeof(node));
memcpy(p,&content,sizeof(node));
ret = pthread_create(&tid[i],NULL,thread_copy,(void *)p);
if(ret != 0)
{
fprintf(stderr,"pthread_create error:%s\n",strerror(ret));
exit(1);
}
}
for(int i=0;i<num+1;i++)
{
ret = pthread_join(tid[i],NULL);
if(ret != 0)
{
fprintf(stderr,"pthread_join error:%s\n",strerror(ret));
exit(1);
}
}
//copy完成输出copy success
printf("copy success\n");
//关闭映射区
munmap(mm,statbuff.st_size);
munmap(mm1,statbuff.st_size);
pthread_exit((void*)0);
}
如有问题,欢迎指正。