• 简单多线程拷贝单文件示例


    整理以前的代码,发现这个还有个尾巴没有做。

    于是花了点时间捡起来。

    代码如下

    View Code
    /*
    * =====================================================================================
    *
    * Filename: copy.c
    *
    * Description: 多线程拷贝文件
    *
    * Version: 1.0
    * Created: 03/17/2012 04:53:09 AM
    * Revision: none
    * Compiler: gcc
    *
    * Author: YOUR NAME (),
    * Company:
    *
    * =====================================================================================
    */
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <pthread.h>
    #include <dirent.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/time.h>

    #define THREADS_COUNT 5
    #define THREADS_BUFF_SIZE 1*108
    /**
    @note 传递到线程的参数
    */
    struct thread_block
    {
    int infd; ///<*文件句柄
    int outfd;
    size_t start;///<*文件的写入起始位置
    size_t end; ///<* 文件写入的终止位置[first ,last)开区间
    };

    void usage()
    {
    printf("copy %%src %%dst\n");
    }
    ///获取文件大小
    size_t get_filesize(int fd)
    {
    struct stat st;

    //memset(&st,0,sizeof(struct stat));
    fstat(fd,&st);
    return st.st_size;
    }
    /**
    @brief 复制Copy线程
    */
    void *thread_copy_fn(void *arg);
    int main(int argc,char *argv[])
    {
    if(argc < 3)
    {
    usage();
    return -1;
    }
    ///打开文件
    int infd = open(argv[1],O_RDONLY);
    int outfd = open(argv[2],O_CREAT|O_WRONLY,0644);
    if(infd == -1|| -1 ==outfd)
    {
    printf("error while open file \n");
    return -1;
    }
    size_t file_size = get_filesize(infd);

    size_t thread_size = THREADS_COUNT;
    ///动态申请,注意释放
    struct thread_block *blocks = (struct thread_block *)
    malloc(sizeof(struct thread_block )* thread_size);
    size_t percent = file_size / thread_size;
    printf("filesize = %d\t percent_blocks = %d\n",\
    file_size,percent);
    int i = 0;
    //init-thread-block
    for(; i < thread_size;++i)
    {
    blocks[i].infd = infd;
    blocks[i].outfd = outfd;
    blocks[i].start = i * percent;
    blocks[i].end = blocks[i].start + percent;
    }
    //the last thread
    blocks[i].end = file_size;
    pthread_t ptid[thread_size];
    ///创建线程
    for(i = 0 ; i < thread_size; ++i)
    {
    pthread_create(&ptid[i],NULL,thread_copy_fn,&(blocks[i]));
    }
    ///线程Join
    for(i = 0 ; i < thread_size; ++i)
    {
    pthread_join(ptid[i],NULL);
    }
    ///释放资源
    free(blocks);
    close(infd);
    close(outfd);
    printf("Copy Successfully \n");
    return 0;
    }

    /**
    * @brief 线程实现函数
    *
    */
    void *thread_copy_fn(void *arg)
    {
    struct thread_block *block = (struct thread_block *)arg;
    char buf[THREADS_BUFF_SIZE];
    int ret;
    size_t count = block->start;

    printf("In Thread\t%ld\nstart = %ld\t end = %ld\n",\
    pthread_self(),block->start,block->end);

    ///lseek到同样的位置
    ret = lseek(block->infd,block->start,SEEK_SET);
    ret = lseek(block->outfd,block->start,SEEK_SET);
    int bytes_read;
    int bytes_write;
    while(count < block->end)
    {
    bytes_read = read(block->infd,buf,sizeof(buf));
    if(bytes_read >0)
    {
    printf("thread = %ld\t read = %ld\t count %d\n",\
    pthread_self(),bytes_read,count);
    count += bytes_read;

    //error while read
    if((bytes_read == -1)&&(errno !=EINTR))
    break;
    char *ptr_write = buf;
    //悲剧的少了个括号,于是bytes_write == 1
    while((bytes_write = write(block->outfd,ptr_write,bytes_read))!=0)
    {
    if((bytes_write == -1)&&(errno!=EINTR))
    break;
    if(bytes_write == bytes_read)
    break;
    else if(bytes_write > 0)
    {
    ptr_write += bytes_write;
    bytes_read -= bytes_write;
    }
    printf("thread = %ld\t write = %ld\t read %d\n",\
    pthread_self(),bytes_write,bytes_read);
    }//end-write;
    ///error while write
    if(bytes_write == -1)
    break;

    }//end-if
    }//end-read
    printf("#####Thread exit %ld#####\n",pthread_self());
    pthread_exit(NULL);
    }

    输入 ./a.out copy.c copy.c.bk > log

    结果如下



    相关解释

    1.两个宏定义,可以修改

    2.针对参数还可以更加多样化。

    3.由于是从不同的地方读取和写入到不同的位置,所以对线程没有做任何同步操作。

    4.不存在共享数据,由于线程中的buf是线程栈中的数据,不存在共享的问题,所以也不需要做互斥。

    5.下一步可以考虑添加监视线程,这样可以达到线程之间的通信功能。

    6.线程的调度功能,当一个线程完成自己的任务时,从新获取新的任务执行——需要实现一个任务队列。

    参考资料

    linux下c语言多线程文件复制

    多线程实现文件拷贝(Linux下C++)

  • 相关阅读:
    期待已久的Ext JS 4.0正式版发布了
    数学学科读到硕士也只是学了皮毛
    数据库迁移
    ExtJS 4正式版今天发布
    BizTalk Server 2010 支持 SFTP 适配器
    MySQL大小写问题
    V$SESSION_LONGOPS
    利用Ganymed SSH2模拟SSH操作
    [Linux] 访问Samba提示“Network path was not found”
    Oracle段高水位(HWM, high water mark)问题
  • 原文地址:https://www.cnblogs.com/westfly/p/2404752.html
Copyright © 2020-2023  润新知