首页 > 系统相关 >多线程多进程拷贝文件Linux&c

多线程多进程拷贝文件Linux&c

时间:2022-11-02 17:36:44浏览次数:45  
标签:tmp src dest char Linux path 拷贝 多线程 dir

多进程拷贝文件

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()来创建线程。其函数结构如下:image
2.各个参数的含义是:

  1. pthread_t *thread:传递一个 pthread_t 类型的指针变量,也可以直接传递某个 pthread_t 类型变量的地址。pthread_t 是一种用于表示线程的数据类型,每一个 pthread_t 类型的变量都可以表示一个线程。

  2. const pthread_attr_t *attr:用于手动设置新建线程的属性,例如线程的调用策略、线程所能使用的栈内存的大小等。大部分场景中,我们都不需要手动修改线程的属性,将 attr 参数赋值为 NULL,pthread_create() 函数会采用系统默认的属性值创建线程。

  3. void (start_routine) (void ):以函数指针的方式指明新建线程需要执行的函数,该函数的参数最多有 1 个(可以省略不写),形参和返回值的类型都必须为 void 类型。void* 类型又称空指针类型,表明指针所指数据的类型是未知的。使用此类型指针时,我们通常需要先对其进行强制类型转换,然后才能正常访问指针指向的数据。

  4. 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;

}


标签:tmp,src,dest,char,Linux,path,拷贝,多线程,dir
From: https://www.cnblogs.com/NKshen/p/mulprocess_thread.html

相关文章

  • Linux 循环,格式以及使用方法
    ​for循环:(每读取一行在字符串下面添加#号)[root@localhost]#cat/etc/passwd|awk-F':''{print$3}'|tail-5>test1.txt[root@localhost]#cattest1.txt98972......
  • Linux安全
    一、Linux防火墙firewalld1.1、firewalld概述支持网络区域所定义的网络链接以及接口安全等级的动态防火墙管理工具工作在网络层支持IPv4、IPv6防火墙设置以及以太网桥......
  • linux 如何使用sh自动输入用户名和密码,并执行命令?
    因为工作需要,需要进入到内部设备执行命令 解决:1.复杂情况,需要输入账号密码和命令。#!/bin/bashlogin_sh(){{sleep1echo......
  • 【记录】配置linux python远程开发环境
    1、安装miniconda下载minicondawgethttps://repo.anaconda.com/miniconda/Miniconda3-py38_4.12.0-Linux-x86_64.sh安装minicondabashMin......
  • 给Linux虚拟机扩展磁盘空间(CentOS7为例)_F_hawk189_新浪博客
    方法是创建一个新的逻辑分区,将新的逻辑分区格式化ext3(或其他类型)的文件系统,mount到磁盘空间不够的文件系统,就跟原来的分区/文件系统一样的使用。首先在VMware设置中扩容之......
  • Cpolar在Linux系统中的应用(网页篇1)
    系列文章​​Cpolar在Linux系统中的安装​​​​如何设置cpolar开机自启动(Linux版)​​​​Cpolar在Linux系统中的应用(网页篇1)​​​​Cpolar在Linux系统中的应用(网页篇2)​​......
  • Cpolar在Linux系统中的应用(网页篇3)
    系列文章​​Cpolar在Linux系统中的安装​​​​如何设置cpolar开机自启动(Linux版)​​​​Cpolar在Linux系统中的应用(网页篇1)​​​​Cpolar在Linux系统中的应用(网页篇2)​​......
  • Cpolar在Linux系统中的应用(设置自定义域名)
    系列文章​​Cpolar在Linux系统中的安装​​​​如何设置cpolar开机自启动(Linux版)​​​​Cpolar在Linux系统中的应用(网页篇1)​​​​Cpolar在Linux系统中的应用(网页篇2)​​......
  • 使用cpolar连接不同操作系统(windows与linux)(2)
     系列文章​​不同操作系统间如何进行TCP连接(Linux版)​​​​使用cpolar进行TCP临时连接(Linux版)​​​​使用cpolar进行TCP稳定连接(Linux版)​​​​使用cpolar连接不同操作......
  • 多线程中的wait与join
        wait一个Object的方法,目的是将调用obj.wait()的线程置为waiting的状态,等待其他线程调用obj.notify()或者obj.notifyAll()来唤醒。最常见的就算生产者/......