您的位置:首页 > 运维架构 > Linux

Linux学习之----多线程复制文件练习

2020-04-07 12:31 1126 查看
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#include <string.h>

pthread_mutex_t mutex;

int string2Int(const char* str)
{
int ret = 0;

if(str != NULL)
{
int len = strlen(str);

for(int i = len - 1;i >= 0;i--)
{
int v = str[i] - '0';

if((0 <= v) && (v <= 9))
{
ret += static_cast<int>((pow(10,len - i - 1) * v));
}
else
{
return -1;
}
}
}
else
{
ret = -1;
}

return ret;
}

struct CopyInfo
{
int rfd;
int wfd;
int off_set; //start pos
int size;
};

void* copyFile(void* arg)
{
CopyInfo* ci = reinterpret_cast<CopyInfo*>(arg);

if(ci != NULL)
{
pthread_mutex_lock(&mutex);

int ret = lseek(ci->rfd,ci->off_set,SEEK_SET);

if(ret != -1)
{
char* buf = new char[ci->size];

if(buf != NULL)
{
ret = read(ci->rfd,buf,ci->size);

if(ret != -1)
{
ret = lseek(ci->wfd,ci->off_set,SEEK_SET);

if(ret != -1)
{
ret = write(ci->wfd,buf,ci->size);

if(ret != -1)
{
printf("thread %lu has succeeded to copy file,off_set = %d,size = %d\n",pthread_self(),ci->off_set,ci->size);
pthread_mutex_unlock(&mutex);
}
else
{
pthread_mutex_unlock(&mutex);
perror("CopyFile : write error ");
exit(1);
}
}
else
{
pthread_mutex_unlock(&mutex);
perror("CopyFile : lseek error ");
exit(1);
}
}
else
{
pthread_mutex_unlock(&mutex);
perror("CopyFile : read error ");
exit(1);
}

delete[] buf;
}
else
{
pthread_mutex_unlock(&mutex);
printf("CopyFile : No enough memory ...\n");
exit(1);
}
}
else
{
pthread_mutex_unlock(&mutex);
perror("CopyFile : lseek error ");
exit(1);
}
}
else
{
printf("CopyFile : arg is a NULL pointer ...\n");
}

return NULL;
}

//格式  ./app.out  要复制的文件  新的文件名  要开启的线程数

int main(int argc,const char* argv[])
{
int ret = 0;

if(argc < 4)
{
printf("%s : Parameter count must be more than 4 ...\n",argv[0]);
exit(1);
}

int thread_count = string2Int(argv[3]);

if(thread_count < 1)
{
printf("%s : thread count must be more than zero ...\n",argv[0]);
exit(1);
}

int rfd = open(argv[1],O_RDONLY,0644);
int wfd = open(argv[2],O_WRONLY | O_CREAT,0644);

if((rfd == -1) || (wfd == -1))
{
perror("open error ");
exit(1);
}

int fileSize = lseek(rfd,0,SEEK_END);
printf("The size of %s is %d\n",argv[1],fileSize);

if(fileSize == -1)
{
perror("lseek error ");
close(rfd);
close(wfd);
exit(1);
}

ret = ftruncate(wfd,fileSize);

if(ret == -1)
{
perror("ftruncate error ");
close(rfd);
close(wfd);
exit(1);
}

CopyInfo* ci = new CopyInfo[thread_count];
pthread_t* pthread_arr = new pthread_t[thread_count];

pthread_mutex_init(&mutex,NULL);

if((ci == NULL) || (pthread_arr == NULL))
{
printf("main : No enough memory ...\n");
}
else
{
int single_rw_size = static_cast<int>(fileSize * 1.0 / thread_count);

for(int i = 0;i < thread_count;i++)
{
ci[i].rfd = rfd;
ci[i].wfd = wfd;
ci[i].off_set = single_rw_size * i;

if(i != (thread_count - 1))
{
ci[i].size = single_rw_size;
}
else
{
ci[i].size = fileSize - (thread_count - 1) * single_rw_size;
}

ret = pthread_create(&pthread_arr[i],NULL,copyFile,reinterpret_cast<void*>(&ci[i]));
}
}

for(int i = 0;i < thread_count;i++)
{
ret = pthread_join(pthread_arr[i],NULL);

if(ret != 0)
{
perror("pthread_join error ");
break;
}

printf("main : 回收了一个线程,线程id为 : %lu \n",pthread_arr[i]);
}

delete[] ci;
delete[] pthread_arr;

close(rfd);
close(wfd);

pthread_mutex_destroy(&mutex);

return ret;
}

  • 点赞
  • 收藏
  • 分享
  • 文章举报
苏瓜皮 发布了17 篇原创文章 · 获赞 1 · 访问量 1487 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: