多線程拷貝

多線程拷貝和多進程拷貝思路相同,只是把進程換成了線程,提高程序的併發性,代碼如下:

 #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);
 }

如有問題,歡迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章