多进程拷贝文件
1.Linux环境中,c语言我们利用的是fork()函数来创建新进程,通过wait()和waitpid()等函数来等待阻塞进程,通过exit()函数来结束进程。
2.我在单进程中,用的是while(file_info=readdir(src_dp))
当判断一个文件路径是文件夹的时候,它会递归进入,需要很长的时间才能回来。因此我们先创建五个子进程,让五个进程都执行拷贝语句。
``
点击查看代码
int i;
pid_t pid;
for(i=0;i<=5;i++){
pid=fork();
if(pid==0){
break;
}
}
if(i==6){
for(i=0;i<=5;i++) {
wait(NULL);
printf("子进程%d退出",i);
}
} else {
while (file_info = readdir(src_dp)) {
switch (file_info->d_type) {
case DT_DIR:
if (strcmp(file_info->d_name, ".") != 0 && strcmp(file_info->d_name, "..") != 0) {
sprintf(tmp_src_dir, "%s/%s", src_dir_path, file_info->d_name);
_copy_dir(tmp_src_dir, tmp_dest_dir);
}
break;
case DT_BLK:
case DT_CHR:
case DT_FIFO:
case DT_REG:
case DT_SOCK:;
case DT_UNKNOWN:
copy_file(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
case DT_LNK:
copy_link(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
default:
break;
}
}
}
多线程拷贝文件
1.在c语言中,我们利用的是<pthread.h>头文件中的pthread_create()来创建线程。其函数结构如下:
2.各个参数的含义是:
-
pthread_t *thread:传递一个 pthread_t 类型的指针变量,也可以直接传递某个 pthread_t 类型变量的地址。pthread_t 是一种用于表示线程的数据类型,每一个 pthread_t 类型的变量都可以表示一个线程。
-
const pthread_attr_t *attr:用于手动设置新建线程的属性,例如线程的调用策略、线程所能使用的栈内存的大小等。大部分场景中,我们都不需要手动修改线程的属性,将 attr 参数赋值为 NULL,pthread_create() 函数会采用系统默认的属性值创建线程。
-
void (start_routine) (void ):以函数指针的方式指明新建线程需要执行的函数,该函数的参数最多有 1 个(可以省略不写),形参和返回值的类型都必须为 void 类型。void* 类型又称空指针类型,表明指针所指数据的类型是未知的。使用此类型指针时,我们通常需要先对其进行强制类型转换,然后才能正常访问指针指向的数据。
-
void *arg:指定传递给 start_routine 函数的实参,当不需要传递任何数据时,将 arg 赋值为 NULL 即可。
点击查看代码
struct myparm a[100];
pthread_t tid[100];
int i=0;
while (file_info = readdir(src_dp))
{ a[i].file_info=file_info;
a[i].dest_dir=tmp_dest_dir;
a[i].src_dir=src_dir_path;
pthread_create(&tid[i], NULL, mypthreadFunction, (void *) &a[i]);
i++;
}
项目总代码
多进程
点击查看代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#include <string.h>
#include <libgen.h>
#include <unistd.h>
#include <stdlib.h>
void copy_file(char *dest_dir, char *src_dir, char *filename)
{
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
sprintf(tmp_dest_dir, "%s/%s", dest_dir, filename);
sprintf(tmp_src_dir, "%s/%s", src_dir, filename);
FILE *src_fp = fopen(tmp_src_dir, "r");
if (!src_fp)
{
("open file error!");
return;
}
FILE *dest_fp = fopen(tmp_dest_dir, "w");
if (!dest_fp)
{
perror("open file error!");
return;
}
char buffer[1024 * 128];
char *tmp;
int rd_ret;
int wr_ret;
while (1)
{
rd_ret = fread(buffer, 1, sizeof(buffer), src_fp);
if (rd_ret == 0)
{
break;
}
tmp = buffer;
while (1)
{
wr_ret = fwrite(tmp, 1, rd_ret, dest_fp);
if (wr_ret == rd_ret)
{
break;
}
else
{
rd_ret -= wr_ret;
}
}
}
fclose(src_fp);
fclose(dest_fp);
}
void copy_link(char *dest_dir, char *src_dir, char *filename)
{
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
sprintf(tmp_dest_dir, "%s/%s", dest_dir, filename);
sprintf(tmp_src_dir, "%s/%s", src_dir, filename);
char path[1024];
char dest[1024];
int result = readlink(tmp_src_dir, path, 1023);
path[result] = '\0';
symlink(path, tmp_dest_dir);
}
void _copy_dir(char *src_dir_path, char *dest_dir_path)
{
if (strcmp(src_dir_path, ".") == 0 || strcmp(src_dir_path, "..") == 0)
{
return;
}
DIR *src_dp, *dest_dp;
struct dirent *file_info;
src_dp = opendir(src_dir_path);
if (src_dp == NULL)
{
return;
}
int dir_len = strlen(src_dir_path);
if (src_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
dir_len = strlen(dest_dir_path);
if (dest_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
char str[] = "linux-5.19.12";
int flag = strcmp(basename(src_dir_path), str);
if (flag != 0)
{
sprintf(tmp_dest_dir, "%s/%s", dest_dir_path, basename(src_dir_path));
}
else
{
strcpy(tmp_dest_dir, dest_dir_path);
}
dest_dp = opendir(tmp_dest_dir);
if (dest_dp == NULL)
{
mkdir(tmp_dest_dir, 0777);
}
else
{
closedir(dest_dp);
}
while (file_info = readdir(src_dp)) {
switch (file_info->d_type) {
case DT_DIR:
if (strcmp(file_info->d_name, ".") != 0 && strcmp(file_info->d_name, "..") != 0) {
sprintf(tmp_src_dir, "%s/%s", src_dir_path, file_info->d_name);
_copy_dir(tmp_src_dir, tmp_dest_dir);
}
break;
case DT_BLK:
case DT_CHR:
case DT_FIFO:
case DT_REG:
case DT_SOCK:;
case DT_UNKNOWN:
copy_file(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
case DT_LNK:
copy_link(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
default:
break;
}
}
closedir(src_dp);
}
void _copy_dir2(char *src_dir_path, char *dest_dir_path)
{
if (strcmp(src_dir_path, ".") == 0 || strcmp(src_dir_path, "..") == 0)
{
return;
}
DIR *src_dp, *dest_dp;
struct dirent *file_info;
src_dp = opendir(src_dir_path);
if (src_dp == NULL)
{
return;
}
int dir_len = strlen(src_dir_path);
if (src_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
dir_len = strlen(dest_dir_path);
if (dest_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
char str[] = "linux-5.19.12";
int flag = strcmp(basename(src_dir_path), str);
if (flag != 0)
{
sprintf(tmp_dest_dir, "%s/%s", dest_dir_path, basename(src_dir_path));
}
else
{
strcpy(tmp_dest_dir, dest_dir_path);
}
dest_dp = opendir(tmp_dest_dir);
if (dest_dp == NULL)
{
mkdir(tmp_dest_dir, 0777);
}
else
{
closedir(dest_dp);
}
int i;
pid_t pid;
for(i=0;i<=5;i++){
pid=fork();
if(pid==0){
break;
}
}
if(i==6){
for(i=0;i<=5;i++) {
wait(NULL);
printf("子线程%d退出",i);
}
} else {
while (file_info = readdir(src_dp)) {
switch (file_info->d_type) {
case DT_DIR:
if (strcmp(file_info->d_name, ".") != 0 && strcmp(file_info->d_name, "..") != 0) {
sprintf(tmp_src_dir, "%s/%s", src_dir_path, file_info->d_name);
_copy_dir(tmp_src_dir, tmp_dest_dir);
}
break;
case DT_BLK:
case DT_CHR:
case DT_FIFO:
case DT_REG:
case DT_SOCK:;
case DT_UNKNOWN:
copy_file(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
case DT_LNK:
copy_link(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
default:
break;
}
}
}
closedir(src_dp);
}
void copy_dir(char *src_dir_path, char *dest_dir_path)
{
DIR *dest_dp;
dest_dp = opendir(dest_dir_path);
if (dest_dp == NULL)
{
if (mkdir(dest_dir_path, 0777) == -1)
{
perror("mkdir error!\n");
return;
}
}
else
{
closedir(dest_dp);
}
_copy_dir2(src_dir_path, dest_dir_path);
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("argc error!\n");
return -1;
}
copy_dir(argv[1], argv[2]);
return 0;
}
点击查看代码
//
// Created by 瞿立燊 on 2022/11/1.
//
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#include <string.h>
#include <libgen.h>
#include <unistd.h>
#include <stdlib.h>
#include<pthread.h>
pthread_mutex_t mutex ;
struct myparm{
struct dirent *file_info;
char *dest_dir;
char *src_dir;
};
void copy_file(char *dest_dir, char *src_dir, char *filename)
{
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
sprintf(tmp_dest_dir, "%s/%s", dest_dir, filename);
sprintf(tmp_src_dir, "%s/%s", src_dir, filename);
FILE *src_fp = fopen(tmp_src_dir, "r");
if (!src_fp)
{
("open file error!");
return;
}
FILE *dest_fp = fopen(tmp_dest_dir, "w");
if (!dest_fp)
{
perror("open file error!");
return;
}
char buffer[1024 * 128];
char *tmp;
int rd_ret;
int wr_ret;
while (1)
{
rd_ret = fread(buffer, 1, sizeof(buffer), src_fp);
if (rd_ret == 0)
{
break;
}
tmp = buffer;
while (1)
{
wr_ret = fwrite(tmp, 1, rd_ret, dest_fp);
if (wr_ret == rd_ret)
{
break;
}
else
{
rd_ret -= wr_ret;
tmp += wr_ret;
}
}
}
fclose(src_fp);
fclose(dest_fp);
}
void copy_link(char *dest_dir, char *src_dir, char *filename)
{
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
sprintf(tmp_dest_dir, "%s/%s", dest_dir, filename);
sprintf(tmp_src_dir, "%s/%s", src_dir, filename);
char path[1024];
char dest[1024];
int result = readlink(tmp_src_dir, path, 1023);
path[result] = '\0';
symlink(path, tmp_dest_dir);
}
void _copy_dir2(char *src_dir_path, char *dest_dir_path)
{
if (strcmp(src_dir_path, ".") == 0 || strcmp(src_dir_path, "..") == 0)
{
return;
}
DIR *src_dp, *dest_dp;
struct dirent *file_info;
src_dp = opendir(src_dir_path);
if (src_dp == NULL)
{
return;
}
int dir_len = strlen(src_dir_path);
if (src_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
dir_len = strlen(dest_dir_path);
if (dest_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
char str[] = "linux-5.19.12";
int flag = strcmp(basename(src_dir_path), str);
if (flag != 0)
{
sprintf(tmp_dest_dir, "%s/%s", dest_dir_path, basename(src_dir_path));
}
else
{
strcpy(tmp_dest_dir, dest_dir_path);
}
dest_dp = opendir(tmp_dest_dir);
if (dest_dp == NULL)
{
mkdir(tmp_dest_dir, 0777);
}
else
{
closedir(dest_dp);
}
while (file_info = readdir(src_dp)) {
switch (file_info->d_type) {
case DT_DIR:
if (strcmp(file_info->d_name, ".") != 0 && strcmp(file_info->d_name, "..") != 0) {
sprintf(tmp_src_dir, "%s/%s", src_dir_path, file_info->d_name);
_copy_dir2(tmp_src_dir, tmp_dest_dir);
}
break;
case DT_BLK:
case DT_CHR:
case DT_FIFO:
case DT_REG:
case DT_SOCK:;
case DT_UNKNOWN:
copy_file(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
case DT_LNK:
copy_link(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
default:
break;
}
}
closedir(src_dp);
}
void* mypthreadFunction(void* pvoid);
void _copy_dir(char *src_dir_path, char *dest_dir_path)
{
if (strcmp(src_dir_path, ".") == 0 || strcmp(src_dir_path, "..") == 0)
{
return;
}
DIR *src_dp, *dest_dp;
struct dirent *file_info;
src_dp = opendir(src_dir_path);
if (src_dp == NULL)
{
return;
}
int dir_len = strlen(src_dir_path);
if (src_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
dir_len = strlen(dest_dir_path);
if (dest_dir_path[dir_len - 1] == '/')
{
src_dir_path[dir_len - 1] = '\0';
}
char tmp_src_dir[512] = {0};
char tmp_dest_dir[512] = {0};
char str[] = "linux-5.19.12";
int flag = strcmp(basename(src_dir_path), str);
if (flag != 0)
{
sprintf(tmp_dest_dir, "%s/%s", dest_dir_path, basename(src_dir_path));
}
else
{
strcpy(tmp_dest_dir, dest_dir_path);
}
dest_dp = opendir(tmp_dest_dir);
if (dest_dp == NULL)
{
mkdir(tmp_dest_dir, 0777);
}
else
{
closedir(dest_dp);
}
struct myparm a[100];
pthread_t tid[100];
int i=0;
while (file_info = readdir(src_dp))
{ a[i].file_info=file_info;
a[i].dest_dir=tmp_dest_dir;
a[i].src_dir=src_dir_path;
pthread_create(&tid[i], NULL, mypthreadFunction, (void *) &a[i]);
i++;
}
while(i>0){
pthread_join(tid[i-1],NULL);
i--;
}
closedir(src_dp);
}
void* mypthreadFunction(void* pvoid){
struct myparm *a=(struct myparm*)pvoid;
struct dirent *file_info=a->file_info;
char *src_dir_path=a->src_dir;
char *tmp_dest_dir=a->dest_dir;
char tmp_src_dir[512] = {0};
DIR *src_dp;
src_dp = opendir(src_dir_path);
if (src_dp == NULL)
{
pthread_exit(0);
}
switch (file_info->d_type) {
case DT_DIR:
if (strcmp(file_info->d_name, ".") != 0 && strcmp(file_info->d_name, "..") != 0) {
sprintf(tmp_src_dir, "%s/%s", src_dir_path, file_info->d_name);
_copy_dir2(tmp_src_dir, tmp_dest_dir);
}
break;
case DT_BLK:
case DT_CHR:
case DT_FIFO:
case DT_REG:
case DT_SOCK:;
case DT_UNKNOWN:
copy_file(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
case DT_LNK:
copy_link(tmp_dest_dir, src_dir_path, file_info->d_name);
break;
default:
break;
}
}
void copy_dir(char *src_dir_path, char *dest_dir_path)
{
DIR *dest_dp;
dest_dp = opendir(dest_dir_path);
if (dest_dp == NULL)
{
if (mkdir(dest_dir_path, 0777) == -1)
{
perror("mkdir error!\n");
return;
}
}
else
{
closedir(dest_dp);
}
_copy_dir(src_dir_path, dest_dir_path);
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("argc error!\n");
return -1;
}
copy_dir(argv[1], argv[2]);
return 0;
}