`
mfcai
  • 浏览: 409207 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多
1、具体思路
把一个文件分成N份,分别用N个线程copy,
每个线程只读取指定长度字节大小的内容
最后一个线程的源文件所指定的结束位置是文件的实际大小
每个线程读取指定源文件部分的起始位置和结束位置的内容到缓冲区
每个线程将缓存中的内容写入目的文件的指定开始位置和结束位置
主线程必须等到所有线程copy完成后才能退出

2.有关文件操作的函数
2.1. 文件的打开和关闭
2.1.1 open()函数
       open()函数的作用是打开文件, 其调用格式为:
         int open(char *filename, int access); 
  该函数表示按access的要求打开名为filename的文件,
  返回值为文件描述字
  open()函数打开成功, 返回值就是文件描述字的值(非负值), 否则返回-1。  
2.1.2 close()函数
       close()函数的作用是关闭由open()函数打开的文件, 其调用格式为:
          int close(int handle); 
       该函数关闭文件描述字handle相连的文件。
2.2.读写函数
2.2.1 read()函数
       read()函数的调用格式为:
          int read(int handle, void *buf, int count); 
       read()函数从handle(文件描述字)相连的文件中, 读取count个字节放到buf所指的缓冲区中,
       返回值为实际所读字节数, 返回-1表示出错。返回0 表示文件结束。

2.2.2 write()函数
       write()函数的调用格式为:
          int write(int handle, void *buf, int count); 

       write()函数把count个字节从buf指向的缓冲区写入与handle相连的文件中,
       返回值为实际写入的字节数
2.3.随机定位函数
lseek()函数
       lseek()函数的调用格式为:
         int lseek(int handle, long offset, int fromwhere); 
       该函数对与handle相连的文件位置指针进行定位, 功能和用法与fseek() 函数相同。

3.源文件(copyfn.c)
源文件在ubuntu10.04下编译通过

#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 3
#define THREADS_BUFF_SIZE 1*1024
struct thread_block
{
    int infd; ///源文件句柄
    int outfd;//目的文件句柄
    size_t start;///文件的写入起始位置
    size_t end; ///文件写入的终止位置
};

void usage()
{
    printf("copy %%src %%dst\n");
}
///获取文件大小
size_t get_filesize(int fd)
{
    struct stat st;
    fstat(fd,&st);
    return st.st_size;
}
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);
    // 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;
}

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;

            //read()返回-1,同时errno为EINTR,表示读的过程中遇到了中断
            if((bytes_read == -1)&&(errno !=EINTR))
                    break;
            char *ptr_write = buf;
            while((bytes_write = write(block->outfd,ptr_write,bytes_read))!=0)
            {
                //write()会返回-1,同时errno为EINTR,表示在写的过程中遇到了中断
                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;
            
        }
    }
    printf("#####Thread exit %ld#####\n",pthread_self());
    pthread_exit(NULL); 
} 


本文欢迎转载,转载请注明作者与出处
作者:流星
出处:http://blog.sina.com.cn/staratsky
分享到:
评论

相关推荐

    Linux下C语言编程--线程操作

    `pthread`库提供了一系列API,使得开发者能够轻松地在C语言中实现多线程功能。 #### 二、线程的基本创建和使用 在Linux下创建和管理线程主要依赖于`pthread`库中的几个关键函数: 1. **`pthread_create`**: 创建...

    linux及c语言库函数精华大全

    5. 多线程编程:利用`pthread.h`库进行并发处理,提高程序性能。 6. 指针操作:熟练掌握指针的概念,利用指针进行高效的数据传递和操作。 四、Ubuntu系统与C语言结合 Ubuntu作为一款流行的Linux发行版,内置了丰富...

    linux下c语言函数库参考手册

    这份手册不仅提供了C语言在Linux系统中的核心功能与应用指南,还深入介绍了如何利用这些函数来优化程序性能、处理文件I/O、网络通信、内存管理以及多线程编程等。 ### 一、标准输入输出函数 在C语言中,`stdio.h`...

    multisum_nowmnh_C语言_多进程_多线程linux_

    本文将深入探讨C语言在Linux环境下实现多进程和多线程的累计和运算,以及两者之间的差异和应用场景。 首先,我们要理解什么是多进程和多线程。多进程是指一个应用程序可以同时启动多个独立的执行单元,每个执行单元...

    c语言多进程多线程编程.pdf

    ### C语言多进程多线程编程相关知识点 #### 进程与线程的基本概念 - **进程**: 进程是一个程序在计算机上的一次执行活动。它是系统进行资源分配和调度的基本单位,拥有独立的地址空间和其他资源。进程之间相互独立...

    C语言实现简单线程池.zip

    在本项目"简单线程池"中,我们将重点探讨如何用C语言在Linux环境下实现这样一个线程池系统,特别是关注其核心组件和设计原则。 首先,线程池的核心概念是线程复用,通过预先创建一组线程,可以避免频繁地创建和销毁...

    Linux下c语言编程实验讲义.docx

    本讲义主要涵盖了 Linux 下 C 语言编程的基础知识和实践经验,涵盖了 Linux 系统基本 shell 指令、文件操作、编译器与多文件交叉包含、库文件的创立与使用、进程与线程程序调试等多个方面的内容。 一、 Linux 系统...

    Linux C语言函数手册

    《Linux C语言函数手册》是C程序员在Linux环境下不可或缺的参考资料。这本手册详细记录了C语言中的各种标准库函数,以及与Linux系统接口相关的函数,对于深入理解和使用C语言编程至关重要。以下将对其中的一些关键...

    c语言多进程多线程编程.doc

    在计算机编程领域,C语言是一种强大的工具,尤其在实现多进程和多线程编程时。多进程和多线程是操作系统中并行处理任务的关键机制,它们允许程序充分利用计算机的硬件资源,提高效率和响应速度。本文将深入探讨C语言...

    demo.rar线程池、文件io拷贝

    该项目使用了线程池进行多线程文件快速的拷贝,可同时复制不同的文件,在不同情况下和不同文件类型的文件以及多重嵌套的文件,该程序都能完美的进行拷贝。用户在使用时,需要输入两个参数,第一个是必须存在的复制...

    Linux_c语言函数库

    以上只是Linux_c语言函数库中的一部分,实际库中还包括了数学运算、时间处理、随机数生成等更多功能。通过深入学习和理解这些函数库,开发者可以更好地利用C语言进行Linux系统级别的编程,开发高效且可靠的软件。...

    Linux下用C实现ATM系统.zip

    在本项目中,我们关注的是如何在Linux操作系统环境下使用C语言来实现一个自动取款机(ATM)系统。这个系统可能包括多个功能模块,如客户登录、转账、存款、取款、解锁、销毁账户、保存数据以及更改密码等。通过分析...

    C语言库函数,Linux C语言函数大全,C语言编程宝典

    总结,C语言库函数是C语言编程的核心,Linux环境下的C语言更加强调与系统的交互。通过深入学习和实践,开发者不仅可以熟练运用这些函数解决问题,还能更好地理解和利用Linux系统的强大功能,为软件开发带来更大的...

    Linux C语言函数大全

    Linux支持多线程编程,`pthread_create()` 创建线程,`pthread_join()` 等待线程结束,`pthread_mutex_t` 用于互斥锁,确保并发访问资源的安全。 六、信号处理 `signal()` 和 `raise()` 函数用于处理和发送信号,...

    Linux C语言函数大全(htm 版,比较全)

    在Linux环境下,C语言与操作系统紧密关联,可以访问系统调用,进行文件操作、进程控制、网络通信等。例如,`fork`用于创建子进程,`exec`系列函数用于执行新的程序,`pipe`和`socket`用于进程间通信,`signal`处理...

    linux下c编程资料

    通过深入学习这个压缩包中的资料,你不仅可以掌握C语言的基础,还能了解到如何在Linux环境下编写和调试程序,甚至可以涉及更高级的主题,如网络编程、多线程编程、系统级编程等。这些知识对于软件开发、系统管理员...

    linux C实现飞机订票系统代码

    Linux下的C语言实现飞机订票系统是一个典型的命令行应用程序开发案例,它涉及到多个核心的编程概念和技术。这个系统通过模块化的代码结构,有效地管理和处理航班信息以及乘客的订票、退票操作。以下是对该系统相关...

    Linux C语言函数大全.zip

    "Linux C语言函数大全.zip"这个文件很可能是包含了一份详尽的C语言函数参考手册,专为在Linux环境下编程的开发者设计。 在Linux环境下使用C语言编程,开发者会接触到一系列与标准C库相关的函数,以及特定于Linux的...

Global site tag (gtag.js) - Google Analytics