您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“LINUX怎么實(shí)現(xiàn)多線程進(jìn)行cp復(fù)制”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“LINUX怎么實(shí)現(xiàn)多線程進(jìn)行cp復(fù)制”這篇文章吧。
關(guān)于這個(gè)問(wèn)題,意義雖然有限因?yàn)橐话銇?lái)說(shuō)在復(fù)制文件的時(shí)候,實(shí)際的瓶頸來(lái)自于I/O,不管開(kāi)啟多少個(gè)線程實(shí)際上速度并不會(huì)快多少,但是為了練習(xí)多線程編程,
這里給出了一種C++代碼實(shí)現(xiàn)的方式,代碼附在最后。
實(shí)際上就是將一個(gè)文件分割為多個(gè)片段,開(kāi)啟多個(gè)線程進(jìn)行同時(shí)復(fù)制,如果用戶制定的并行大于服務(wù)器實(shí)際的CPU核數(shù),程序會(huì)自動(dòng)降級(jí)并行度為CPU核數(shù),如果文件小于
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!!
復(fù)制完成后進(jìn)行md5驗(yàn)證
root@bogon:/home/gaopeng/mmm# md5sum log.log
f64acc21f7187a865938b340b3eda198 log.log
root@bogon:/home/gaopeng/mmm# md5sum log10.log
f64acc21f7187a865938b340b3eda198 log10.log
可以看出校驗(yàn)是通過(guò)的
代碼如下:
點(diǎn)擊(此處)折疊或打開(kāi)
#include<iostream>
#include <map>
#include<stdint.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <sys/sysinfo.h>
#include<fcntl.h>
#include<errno.h>
#include <time.h>
#include <stdarg.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_BUFFER 65536
using namespace std;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
class thread_info
{
private:
uint64_t start_pos;
uint64_t end_pos;
int fdr;
int fdw;
public:
pthread_t t_id;
static int do_id;
public:
thread_info()
{
start_pos = 0;
end_pos = 0;
fdr = 0;
fdw = 0;
t_id = 0;
}
void set_start(uint64_t a)
{
start_pos = a;
}
void set_end(uint64_t a)
{
end_pos = a;
}
void set_fd(int a,int b)
{
fdr = a;
fdw = b;
}
uint64_t get_start(void)
{
return start_pos;
}
uint64_t get_stop(void)
{
return end_pos;
}
int get_fdr(void)
{
return fdr;
}
int get_fdw(void)
{
return fdw;
}
void print(void)
{
cout<<start_pos<<":"<<end_pos<<":"<<t_id<<endl;
}
};
int thread_info::do_id = 0;
class ABS_dispatch
{
public:
ABS_dispatch()
{
par_thr = 0;
max_cpu = 0;
}
virtual thread_info* call_thread(void) = 0;
virtual void make_init(uint32_t t_n) = 0;
uint32_t getcpu(void)
{
return get_nprocs() ;
}
virtual ~ABS_dispatch(){
}
protected:
uint32_t par_thr;
uint32_t max_cpu;
};
class dispatch:public ABS_dispatch
{
public:
typedef multimap<uint64_t,uint64_t>::iterator pair_piece_iterator;
dispatch():ABS_dispatch()
{
file_idr = 0;
file_idw = 0;
file_size = 0;
tread_arr_p = NULL;
}
virtual thread_info* call_thread(void);
virtual void make_init(uint32_t t_n)
{
max_cpu = getcpu(); //
cout<<"Your cpu core is:"<<max_cpu<<"\n";
if(t_n > max_cpu) //parallel
{
cout<<"Parallel downgrad to cpu core:"<<max_cpu<<"\n";
par_thr = max_cpu;
}
else
{
par_thr = t_n;
}
}
void set_init(int file_idr,int file_idw)
{
file_size = lseek(file_idr,0,SEEK_END);
if(file_size<100000000)
{
cout<<"File small than 100M par = 1" <<"\n";
par_thr = 1;
}
this->file_idr = file_idr;
this->file_idw = file_idw;
}
uint32_t real_par()
{
return par_thr;
}
virtual ~dispatch()
{
pair_piece.clear();
delete [] tread_arr_p;
}
private:
int file_idr;
int file_idw;
multimap<uint64_t,uint64_t> pair_piece;
uint64_t file_size;
public:
thread_info* tread_arr_p;
};
static void* do_work(void* argc)
{
uint64_t b;
uint64_t e;
int fdr;
int fdw;
char* buffer[MAX_BUFFER]={0};
thread_info* tread_arr_p;
uint64_t loopc = 0;
uint64_t loopc25 = 0;
uint64_t i = 0;
int m = 1;
pthread_t t_id;
tread_arr_p = static_cast<thread_info*>(argc);
//臨界區(qū) MUTEX
pthread_mutex_lock(&counter_mutex);
b = (tread_arr_p+ tread_arr_p->do_id)->get_start();
e = (tread_arr_p+ tread_arr_p->do_id)->get_stop();
fdr = (tread_arr_p+ tread_arr_p->do_id)->get_fdr();
fdw = (tread_arr_p+ tread_arr_p->do_id)->get_fdw();
t_id = (tread_arr_p+ tread_arr_p->do_id)->t_id ;
cout<< t_id <<":"<<b<<":"<<e<<":"<<fdr<<":"<<fdw<<"\n";
tread_arr_p->do_id++;
pthread_mutex_unlock(&counter_mutex);
//臨界區(qū)
loopc = e/uint64_t(MAX_BUFFER);
loopc25 = loopc/(uint64_t)4;
while(i<loopc)
{
if(i == loopc25*m )
{
cout<< "Copy Thread:"<<t_id<<" work "<<25*m<<"%\n";
m++;
}
memset(buffer,0,MAX_BUFFER);
pread(fdr,buffer,MAX_BUFFER,uint64_t(i*MAX_BUFFER));
pwrite(fdw,buffer,MAX_BUFFER,uint64_t(i*MAX_BUFFER));
i++;
}
memset(buffer,0,MAX_BUFFER);
pread(fdr,buffer,(e-uint64_t(i*MAX_BUFFER)),uint64_t(i*MAX_BUFFER));
pwrite(fdw,buffer,(e-uint64_t(i*MAX_BUFFER)),uint64_t(i*MAX_BUFFER));
cout<< "Copy Thread:"<<t_id<<" work Ok!!"<<"\n";
return NULL;
}
thread_info* dispatch::call_thread()
{
int i = 0;
uint64_t temp_size = 0;
temp_size = file_size/par_thr;
tread_arr_p = new thread_info[par_thr];
cout<<"Will Create "<<par_thr<<" Threads\n";
//cout<<tread_arr_p<<endl;
//cout<<sizeof(thread_info)<<endl;
for(i = 0;i<par_thr-1;i++)
{
pair_piece.insert( pair<uint64_t,uint64_t>(temp_size*i,temp_size*(i+1)-1 ));
}
pair_piece.insert( pair<uint64_t,uint64_t>(temp_size*i,file_size ));
i = 1;
for(pair_piece_iterator it =pair_piece.begin();it !=pair_piece.end() ;it++)
{
//cout<<"--Thread: "<<i<<"\n";
//cout<<it->first<<"\n";
//cout<<it->second<<"\n";
//cout<<tread_arr_p+(i-1)<<endl;
(tread_arr_p+(i-1))->set_start(it->first);
(tread_arr_p+(i-1))->set_end(it->second);
(tread_arr_p+(i-1))->set_fd(file_idr,file_idw);
pthread_create(&((tread_arr_p+(i-1))->t_id),NULL,do_work,static_cast<void*>(tread_arr_p));
//(tread_arr_p+(i-1))->print();
i++;
}
return tread_arr_p;
}
int main(int argc,char** argv)
{
dispatch test;
thread_info* thread_info_p = NULL;
uint32_t real_par;
void *tret;
int fdr = open(argv[1],O_RDONLY|O_NOFOLLOW);
int fdw = open(argv[2],O_RDWR|O_CREAT|O_EXCL,0755);
cout<<"Author: gaopeng QQ:22389860 Blog:http://blog.itpub.net/7728585\n";
if(argc<4)
{
cout<<"USAGE:parcp sourcefile destfile paralle\n";
return -1;
}
if(fdr == -1 || fdw == -1)
{
perror("open readfile:");
return -1;
}
if(fdw == -1)
{
perror("open wirtefile:");
return -1;
}
if(sscanf(argv[3],"%u",&real_par) == EOF)
{
perror("sscanf:");
return -1;
}
cout<<"set parallel:"<<real_par<<"\n";
//cout<<lseek(fd,0,SEEK_SET) <<endl;
test.make_init(real_par);
test.set_init(fdr,fdw);
real_par = test.real_par();
cout<<"real parallel:" <<real_par<<"\n";
thread_info_p = test.call_thread();
for(int i = 0 ;i<real_par;i++)
{
//cout<<(thread_info_p+i)->t_id<<endl;
pthread_join((thread_info_p+i)->t_id,&tret);
//cout<<reinterpret_cast<long>(tret)<<endl;
}
close(fdw);
close(fdr);
}
以上是“LINUX怎么實(shí)現(xiàn)多線程進(jìn)行cp復(fù)制”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。