关于这个问题,意义虽然有限因为一般来说在复制文件的时候,实际的瓶颈来自于I/O,不管开启多少个线程实际上速度并不会快多少,但是为了练习多线程编程,
这里给出了一种C++代码实现的方式,代码附在最后。

实际上就是将一个文件分割为多个片段,开启多个线程进行同时复制,如果用户制定的并行大于服务器实际的CPU核数,程序会自动降级并行度为CPU核数,如果文件小于
100M则并行度始终为1。

root@bogon:/home/gaopeng/mmm# ./parcp log.log log10.log 2       
set parallel:2
Your cpu core is:4
real parallel:2
Will Create 2 Threads
140677902710528:0:174522367:3:4
140677894317824:174522368:349044736:3:4
Copy Thread:140677902710528 work 25%
Copy Thread:140677894317824 work 25%
Copy Thread:140677902710528 work 50%
Copy Thread:140677902710528 work 75%
Copy Thread:140677902710528 work 100%
Copy Thread:140677902710528 work Ok!!
Copy Thread:140677894317824 work 50%
Copy Thread:140677894317824 work 75%
Copy Thread:140677894317824 work Ok!!

复制完成后进行md5验证
root@bogon:/home/gaopeng/mmm# md5sum log.log
f64acc21f7187a865938b340b3eda198  log.log
root@bogon:/home/gaopeng/mmm# md5sum log10.log
f64acc21f7187a865938b340b3eda198  log10.log
可以看出校验是通过的

代码如下:

点击(此处)折叠或打开

  1. #include<iostream>
  2. #include <map>
  3. #include<stdint.h>
  4. #include<stdio.h>
  5. #include<string.h>
  6. #include<unistd.h>
  7. #include<sys/types.h>
  8. #include<sys/stat.h>
  9. #include <sys/sysinfo.h>
  10. #include<fcntl.h>
  11. #include<errno.h>
  12. #include <time.h>
  13. #include <stdarg.h>
  14. #include <stdlib.h>
  15. #include <pthread.h>
  16. #define MAX_BUFFER 65536
  17. using namespace std;
  18. pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
  19. class thread_info
  20. {
  21. private:
  22. uint64_t start_pos;
  23. uint64_t end_pos;
  24. int fdr;
  25. int fdw;
  26. public:
  27. pthread_t t_id;
  28. static int do_id;
  29. public:
  30. thread_info()
  31. {
  32. start_pos = 0;
  33. end_pos = 0;
  34. fdr = 0;
  35. fdw = 0;
  36. t_id = 0;
  37. }
  38. void set_start(uint64_t a)
  39. {
  40. start_pos = a;
  41. }
  42. void set_end(uint64_t a)
  43. {
  44. end_pos = a;
  45. }
  46. void set_fd(int a,int b)
  47. {
  48. fdr = a;
  49. fdw = b;
  50. }
  51. uint64_t get_start(void)
  52. {
  53. return start_pos;
  54. }
  55. uint64_t get_stop(void)
  56. {
  57. return end_pos;
  58. }
  59. int get_fdr(void)
  60. {
  61. return fdr;
  62. }
  63. int get_fdw(void)
  64. {
  65. return fdw;
  66. }
  67. void print(void)
  68. {
  69. cout<<start_pos<<":"<<end_pos<<":"<<t_id<<endl;
  70. }
  71. };
  72. int thread_info::do_id = 0;
  73. class ABS_dispatch
  74. {
  75. public:
  76. ABS_dispatch()
  77. {
  78. par_thr = 0;
  79. max_cpu = 0;
  80. }
  81. virtual thread_info* call_thread(void) = 0;
  82. virtual void make_init(uint32_t t_n) = 0;
  83. uint32_t getcpu(void)
  84. {
  85. return get_nprocs() ;
  86. }
  87. virtual ~ABS_dispatch(){
  88. }
  89. protected:
  90. uint32_t par_thr;
  91. uint32_t max_cpu;
  92. };
  93. class dispatch:public ABS_dispatch
  94. {
  95. public:
  96. typedef multimap<uint64_t,uint64_t>::iterator pair_piece_iterator;
  97. dispatch():ABS_dispatch()
  98. {
  99. file_idr = 0;
  100. file_idw = 0;
  101. file_size = 0;
  102. tread_arr_p = NULL;
  103. }
  104. virtual thread_info* call_thread(void);
  105. virtual void make_init(uint32_t t_n)
  106. {
  107. max_cpu = getcpu(); //
  108. cout<<"Your cpu core is:"<<max_cpu<<"\n";
  109. if(t_n > max_cpu) //parallel
  110. {
  111. cout<<"Parallel downgrad to cpu core:"<<max_cpu<<"\n";
  112. par_thr = max_cpu;
  113. }
  114. else
  115. {
  116. par_thr = t_n;
  117. }
  118. }
  119. void set_init(int file_idr,int file_idw)
  120. {
  121. file_size = lseek(file_idr,0,SEEK_END);
  122. if(file_size<100000000)
  123. {
  124. cout<<"File small than 100M par = 1" <<"\n";
  125. par_thr = 1;
  126. }
  127. this->file_idr = file_idr;
  128. this->file_idw = file_idw;
  129. }
  130. uint32_t real_par()
  131. {
  132. return par_thr;
  133. }
  134. virtual ~dispatch()
  135. {
  136. pair_piece.clear();
  137. delete [] tread_arr_p;
  138. }
  139. private:
  140. int file_idr;
  141. int file_idw;
  142. multimap<uint64_t,uint64_t> pair_piece;
  143. uint64_t file_size;
  144. public:
  145. thread_info* tread_arr_p;
  146. };
  147. static void* do_work(void* argc)
  148. {
  149. uint64_t b;
  150. uint64_t e;
  151. int fdr;
  152. int fdw;
  153. char* buffer[MAX_BUFFER]={0};
  154. thread_info* tread_arr_p;
  155. uint64_t loopc = 0;
  156. uint64_t loopc25 = 0;
  157. uint64_t i = 0;
  158. int m = 1;
  159. pthread_t t_id;
  160. tread_arr_p = static_cast<thread_info*>(argc);
  161. //临界区 MUTEX
  162. pthread_mutex_lock(&counter_mutex);
  163. b = (tread_arr_p+ tread_arr_p->do_id)->get_start();
  164. e = (tread_arr_p+ tread_arr_p->do_id)->get_stop();
  165. fdr = (tread_arr_p+ tread_arr_p->do_id)->get_fdr();
  166. fdw = (tread_arr_p+ tread_arr_p->do_id)->get_fdw();
  167. t_id = (tread_arr_p+ tread_arr_p->do_id)->t_id ;
  168. cout<< t_id <<":"<<b<<":"<<e<<":"<<fdr<<":"<<fdw<<"\n";
  169. tread_arr_p->do_id++;
  170. pthread_mutex_unlock(&counter_mutex);
  171. //临界区
  172. loopc = e/uint64_t(MAX_BUFFER);
  173. loopc25 = loopc/(uint64_t)4;
  174. while(i<loopc)
  175. {
  176. if(i == loopc25*m )
  177. {
  178. cout<< "Copy Thread:"<<t_id<<" work "<<25*m<<"%\n";
  179. m++;
  180. }
  181. memset(buffer,0,MAX_BUFFER);
  182. pread(fdr,buffer,MAX_BUFFER,uint64_t(i*MAX_BUFFER));
  183. pwrite(fdw,buffer,MAX_BUFFER,uint64_t(i*MAX_BUFFER));
  184. i++;
  185. }
  186. memset(buffer,0,MAX_BUFFER);
  187. pread(fdr,buffer,(e-uint64_t(i*MAX_BUFFER)),uint64_t(i*MAX_BUFFER));
  188. pwrite(fdw,buffer,(e-uint64_t(i*MAX_BUFFER)),uint64_t(i*MAX_BUFFER));
  189. cout<< "Copy Thread:"<<t_id<<" work Ok!!"<<"\n";
  190. return NULL;
  191. }
  192. thread_info* dispatch::call_thread()
  193. {
  194. int i = 0;
  195. uint64_t temp_size = 0;
  196. temp_size = file_size/par_thr;
  197. tread_arr_p = new thread_info[par_thr];
  198. cout<<"Will Create "<<par_thr<<" Threads\n";
  199. //cout<<tread_arr_p<<endl;
  200. //cout<<sizeof(thread_info)<<endl;
  201. for(i = 0;i<par_thr-1;i++)
  202. {
  203. pair_piece.insert( pair<uint64_t,uint64_t>(temp_size*i,temp_size*(i+1)-1 ));
  204. }
  205. pair_piece.insert( pair<uint64_t,uint64_t>(temp_size*i,file_size ));
  206. i = 1;
  207. for(pair_piece_iterator it =pair_piece.begin();it !=pair_piece.end() ;it++)
  208. {
  209. //cout<<"--Thread: "<<i<<"\n";
  210. //cout<<it->first<<"\n";
  211. //cout<<it->second<<"\n";
  212. //cout<<tread_arr_p+(i-1)<<endl;
  213. (tread_arr_p+(i-1))->set_start(it->first);
  214. (tread_arr_p+(i-1))->set_end(it->second);
  215. (tread_arr_p+(i-1))->set_fd(file_idr,file_idw);
  216. pthread_create(&((tread_arr_p+(i-1))->t_id),NULL,do_work,static_cast<void*>(tread_arr_p));
  217. //(tread_arr_p+(i-1))->print();
  218. i++;
  219. }
  220. return tread_arr_p;
  221. }
  222. int main(int argc,char** argv)
  223. {
  224. dispatch test;
  225. thread_info* thread_info_p = NULL;
  226. uint32_t real_par;
  227. void *tret;
  228. int fdr = open(argv[1],O_RDONLY|O_NOFOLLOW);
  229. int fdw = open(argv[2],O_RDWR|O_CREAT|O_EXCL,0755);
  230. cout<<"Author: gaopeng QQ:22389860 Blog:http://blog.itpub.net/7728585\n";
  231. if(argc<4)
  232. {
  233. cout<<"USAGE:parcp sourcefile destfile paralle\n";
  234. return -1;
  235. }
  236. if(fdr == -1 || fdw == -1)
  237. {
  238. perror("open readfile:");
  239. return -1;
  240. }
  241. if(fdw == -1)
  242. {
  243. perror("open wirtefile:");
  244. return -1;
  245. }
  246. if(sscanf(argv[3],"%u",&real_par) == EOF)
  247. {
  248. perror("sscanf:");
  249. return -1;
  250. }
  251. cout<<"set parallel:"<<real_par<<"\n";
  252. //cout<<lseek(fd,0,SEEK_SET) <<endl;
  253. test.make_init(real_par);
  254. test.set_init(fdr,fdw);
  255. real_par = test.real_par();
  256. cout<<"real parallel:" <<real_par<<"\n";
  257. thread_info_p = test.call_thread();
  258. for(int i = 0 ;i<real_par;i++)
  259. {
  260. //cout<<(thread_info_p+i)->t_id<<endl;
  261. pthread_join((thread_info_p+i)->t_id,&tret);
  262. //cout<<reinterpret_cast<long>(tret)<<endl;
  263. }
  264. close(fdw);
  265. close(fdr);
  266. }

如果觉得不错 您可以考虑请作者喝杯茶(微信支付):                                作者微信号:

                   

LINUX 如何实现多线程进行cp复制相关推荐

  1. Linux学习(4)---cp(复制命令)

    CP(复制命令) 1.复制档案 一.常用cp操作 二.复制档案的权限 2.复制目录 CP(复制命令) 不言而喻,复制功能是我们管理文件的重要手段之一. 在图形化界面上轻轻点击鼠标即可完成,而在Linu ...

  2. Linux CentOS  复制文件、替换文件 cp 复制文件、cp 覆盖文件 cp替换文件

    Linux CentOS  复制文件.替换文件 cp 复制文件.cp 覆盖文件 cp替换文件 一.Linux 复制文件语法 1. cp [option] src dest 2. option 可选参数 ...

  3. linux下的拷贝(cp)、删除(rm)、剪切(mv)命令

    linux下的拷贝(cp).删除(rm).剪切(mv)命令 2010-02-03 10:38 cp命令 该命令的功能是将给出的文件或目录拷贝到另一文件或目录中,就如同DOS下的copy命令一样,功能非 ...

  4. linux下文件操作之cp和mv

    Linux CP文件夹略过目录的解决 root@QGY:/home/qgy# cp image/newimage_raw /mnt/4T/qin/ cp: 略过目录'image/newimage_ra ...

  5. linux命令cp -a,linux命令_ls命令与cp命令详解(一)

    linux命令_ls命令与cp命令详解(1) 最近想详细熟悉下linux命令,学习笔记记录下: 今天主要学习的是目录操作,下面给大家介绍一下今天学到的几个命令: 1.ls命令 功能:显示文件或者目录信 ...

  6. cp——复制文件\文件夹

    cp--复制文件\文件夹 1.作用 cp命令来自英文单词:copy 用于复制文件\文件夹 2.语法 cp [-r] 参数1 参数2 -r选项,可选,用于复制文件夹使用,表示递归 参数1,Linux路径 ...

  7. 嵌入式linux防复制,嵌入式linux /dev 下的文件无法复制

    嵌入式linux /dev 下的文件无法复制 关注:234  答案:4  mip版 解决时间 2021-02-06 06:27 提问者一段小時光 2021-02-06 00:38 root下也有文件不 ...

  8. Linux环境编程--多线程

    本文作者: 姚继锋 (2001-08-11 09:05:00)    时隔多年 原文地址已经无从查...  居然是2001年就写了  今天看来对初学者还是很有参考意义  所以特转给大家 本人在原文基础 ...

  9. cp复制文件和目录的使用举例

    cp - copy files and directories (cp复制文件和目录) cp [OPTION]... [-T] SOURCE DEST (选项)        (源目标) cp [OP ...

最新文章

  1. python培训班哪些比较好-python培训机构哪家比较好?
  2. RabbitMQ 一二事(2) - 工作队列使用
  3. python查找指定文件路径_Python寻找路径和查找文件路径的示例
  4. 武鸣高中2021高考成绩查询,2019年广西两大重点高中成绩大比拼
  5. JSON格式以及基本用法
  6. vue - 父子组件通信之$emit传多个参数
  7. hivesql优化的深入解析
  8. mex文件用matlab能打开吗,matlab中mex文件编译运行的问题
  9. nacos当配置中心读取其他配置文件_SpringBoot+Nacos实现配置中心
  10. UVA 11825 Hackers' Crackdown 状态DP
  11. ROS笔记(9) launch文件
  12. Spring MVC JSR-303验证框架之Hibernate-Validator
  13. wps 选择 高亮_简单实用:一组WPS表格技巧
  14. 2021-06-27面向对象继承
  15. 会计初级可以自己报名吗_2019初级会计职称考试报名流程全攻略
  16. Design1.CMOS工艺OD门,传输门,三态门原理应用浅析
  17. 戒指戴在不同手指上的含义
  18. mysql怎么查询不是张姓的_mysql 中的常用查询
  19. 军队文职(数学2+物理)——高等数学 3、求极限(一)
  20. 武汉地铁站点最短路径搜索的实现(一)——Dijkstra算法(C++ coding)

热门文章

  1. Java中二维数组的用法(不定长二维数组)
  2. python的os模块基本使用
  3. 像@Transactional一样利用注解自定义aop切片
  4. WinForm绘制柱形图
  5. spring-wind 搭建过程问题记录
  6. 【锋利的Jquery】读书笔记五
  7. fread和fwrite函数功能
  8. android手势识别
  9. spring入门:beans.xml不提示、别名、创建对象的三种方式
  10. “豆瓣酱”之用户,场景,功能