多线程目录拷贝
1、多线程拷贝代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h>
#include<string.h>
#include<pthread.h>
#define NUM_OF_THREADS 10
char* src_arr[1000000];
char* des_arr[1000000];
int src_index = 0;
int des_index = 0;
int i = 0;
int len;
pthread_mutex_t mutex;
void copy_file(char *dir_src, char *dir_des){
FILE *src, *dst;
char buf[1024];
printf("src file: %s\n", dir_src);
printf("dst file: %s\n", dir_des);
src = fopen(dir_src, "r+");
dst = fopen(dir_des, "w+");
if(NULL == src){
printf("src error\n");
exit(EXIT_FAILURE);
}
if(NULL == dst){
printf("dst error\n");
exit(EXIT_FAILURE);
}
while(1){
if(len = fread(buf, 1, 1024, src)){
fwrite(buf,1,len, dst);
} else
break;
}
fclose(src);
fclose(dst);
}
void copy_dir(char *src_path, char *dst_path){
DIR *srcdir = opendir(src_path);
if(NULL == srcdir){
printf("open dir %s error, pls check it.\n", src_path);
exit(EXIT_FAILURE);
}
struct dirent *tmp = NULL;
char sub_dir_path[255];
size_t length = strlen(src_path);
memset(sub_dir_path, '\0', 255);
strcpy(sub_dir_path, src_path);
sub_dir_path[length] = '/';
sub_dir_path[length + 1] = '\0';
char dst_dir_path[255];
size_t dstlen = strlen(dst_path);
memset(dst_dir_path, '\0', 255);
strcpy(dst_dir_path, dst_path);
dst_dir_path[dstlen] = '/';
dst_dir_path[dstlen + 1] = '\0';
char *dirname = strrchr(src_path, '/');
//printf("dirname %s\n", dirname);
strcat(dst_dir_path, dirname);
int dst_pre_path_length = strlen(dst_dir_path);
mkdir(dst_dir_path, S_IRUSR|S_IWUSR|S_IXUSR);
while(1){
tmp = readdir(srcdir);
if(NULL == tmp) break;
if(strcmp(".", tmp->d_name) == 0 ||
strcmp("..", tmp->d_name) == 0)
continue;
//1:get source path (file or director)
strcat(sub_dir_path, tmp->d_name);
if(tmp->d_type == DT_DIR){
//printf("sub dir name is: %s\n", tmp->d_name);
cp_dir(sub_dir_path, dst_dir_path);
}else {
//TODO: copy file
//set dst file path
strcat(dst_dir_path, "/");
strcat(dst_dir_path, tmp->d_name);
//printf("src: %s \ndst: %s\n", sub_dir_path, dst_dir_path);
//cp_file(sub_dir_path, dst_dir_path);
src_arr[src_index] = (char*)malloc(255);
strcpy(src_arr[src_index],sub_dir_path);
src_index++;
des_arr[des_index] = (char*)malloc(255);
strcpy(des_arr[des_index],dst_dir_path);
des_index++;
dst_dir_path[dst_pre_path_length] = '\0';
}
// Reset prefix of source path (file or director)
sub_dir_path[length + 1] = '\0';
}
closedir(srcdir);
}
void* run()
{
while(i<des_index)
{
if(pthread_mutex_lock(&mutex)!=0)
{
printf("lock error\n");
pthread_exit(NULL);
}
if(i<des_index)
{
printf("thread: %lu\n",pthread_self());
cp_file(src_arr[i],des_arr[i]);
//printf("srcp: %s \ndstp: %s\n", src_arr[i], des_arr[i]);
i++;
usleep(1);
}
else{
pthread_exit(NULL);
}
pthread_mutex_unlock(&mutex);
usleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char **argv){
if(3 != argc){
printf("USAGE: %s src_dir, dst_disr\n", argv[0]);
exit(EXIT_FAILURE);
}
copy_dir(argv[1], argv[2]);
pthread_mutex_init(&mutex,NULL);
pthread_t threads[NUM_OF_THREADS];
for(int i=0; i<NUM_OF_THREADS; i++){
pthread_create(&threads[i], NULL, run, NULL);
}
for(int i=0; i<NUM_OF_THREADS; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
2、编译代码
运行结果如下:
然后编写MD5测试文件,
#include <openssl/md5.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h>
#include<string.h>
MD5_CTX ctx;
unsigned char out_md5[16];
int len;
void copy_file(char *src_file){
FILE *src, *dst;
char buf[255];
//printf("src file: %s\n", src_file);
//printf("dst file: %s\n", dst_file);
src = fopen(src_file, "r");
if(NULL == src){
printf("srcd error\n");
exit(EXIT_FAILURE);
}
while(1){
if(len = fread(buf,1, 255, src)){
//fputs(buf, dst);
MD5_Update(&ctx,buf,len);
} else
break;
}
fclose(src);
}
void copy_dir(char *src_path){
DIR *srcdir = opendir(src_path);
if(NULL == srcdir){
printf("open dir %s error, pls check it.\n", src_path);
exit(EXIT_FAILURE);
}
struct dirent *tmp = NULL;
char sub_dir_path[255];
size_t length = strlen(src_path);
memset(sub_dir_path, '\0', 255);
strcpy(sub_dir_path, src_path);
sub_dir_path[length] = '/';
sub_dir_path[length + 1] = '\0';
while(1){
tmp = readdir(srcdir);
if(NULL == tmp) break;
if(strcmp(".", tmp->d_name) == 0 ||
strcmp("..", tmp->d_name) == 0)
continue;
//1:get source path (file or director)
strcat(sub_dir_path, tmp->d_name);
if(tmp->d_type == DT_DIR){
//printf("sub dir name is: %s\n", tmp->d_name);
copy_dir(sub_dir_path);
}else {
//TODO: copy file
//set dst file path
//printf("src: %s \ndst: %s\n", sub_dir_path, dst_dir_path);
copy_file(sub_dir_path);
}
// Reset prefix of source path (file or director)
sub_dir_path[length + 1] = '\0';
}
closedir(srcdir);
}
int main(int argc, char **argv)
{
int i=0;
memset(out_md5,0,sizeof(out_md5));
MD5_Init(&ctx);
copy_dir(argv[1]);
MD5_Final(out_md5,&ctx);
for(i=0;i<16;i++)
{
printf("%02X",out_md5[i]);
}
printf("\n");
return 0;
}