转自:https://www.cnblogs.com/zxl0715/articles/5365989.html

、具体思路
把一个文件分成N份,分别用N个线程copy,
每个线程只读取指定长度字节大小的内容
最后一个线程的源文件所指定的结束位置是文件的实际大小
每个线程读取指定源文件部分的起始位置和结束位置的内容到缓冲区
每个线程将缓存中的内容写入目的文件的指定开始位置和结束位置
主线程必须等到所有线程copy完成后才能退出 .有关文件操作的函数
2.1. 文件的打开和关闭
2.1. open()函数
open()函数的作用是打开文件, 其调用格式为:
int open(char *filename, int access);
该函数表示按access的要求打开名为filename的文件,
返回值为文件描述字
open()函数打开成功, 返回值就是文件描述字的值(非负值), 否则返回-。
2.1. close()函数
close()函数的作用是关闭由open()函数打开的文件, 其调用格式为:
int close(int handle);
该函数关闭文件描述字handle相连的文件。
2.2.读写函数
2.2. read()函数
read()函数的调用格式为:
int read(int handle, void *buf, int count);
read()函数从handle(文件描述字)相连的文件中, 读取count个字节放到buf所指的缓冲区中,
返回值为实际所读字节数, 返回-1表示出错。返回0 表示文件结束。 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() 函数相同。 .源文件(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 < )
{
usage();
return -;
}
///打开文件
int infd = open(argv[],O_RDONLY);
int outfd = open(argv[],O_CREAT|O_WRONLY,);
// 0644也就是-文件所有者有读写权限,组有读权限,其他用户有读权限
if(infd == -|| - ==outfd)
{
printf("error while open file \n");
return -;
}
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 = ;
//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 = ; i < thread_size; ++i)
{
pthread_create(&ptid[i],NULL,thread_copy_fn,&(blocks[i]));
}
///线程Join
for(i = ; i < thread_size; ++i)
{
pthread_join(ptid[i],NULL);
}
///释放资源
free(blocks);
close(infd);
close(outfd);
printf("Copy Successfully \n");
return ;
} 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 >)
{
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 == -)&&(errno !=EINTR))
break;
char *ptr_write = buf;
while((bytes_write = write(block->outfd,ptr_write,bytes_read))!=)
{
//write()会返回-1,同时errno为EINTR,表示在写的过程中遇到了中断
if((bytes_write == -)&&(errno!=EINTR))
break;
if(bytes_write == bytes_read)
break;
else if(bytes_write > )
{
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 == -)
break; }
}
printf("#####Thread exit %ld#####\n",pthread_self());
pthread_exit(NULL);
}
本文欢迎转载,转载请注明作者与出处

linux下c语言实现多线程文件复制【转】的更多相关文章

  1. linux 下C语言编程库文件处理与Makefile编写

    做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...

  2. linux下C语言实现多线程通信—环形缓冲区,可用于生产者(producer)/消费者(consumer)【转】

    转自:http://blog.chinaunix.net/uid-28458801-id-4262445.html 操作系统:ubuntu10.04 前言:     在嵌入式开发中,只要是带操作系统的 ...

  3. linux下c语言的多线程编程

    我们在写linux的服务的时候,经常会用到linux的多线程技术以提高程序性能 多线程的一些小知识: 一个应用程序可以启动若干个线程. 线程(Lightweight Process,LWP),是程序执 ...

  4. Linux下c语言TCP多线程聊天室

    开发环境:Linux,GCC 相关知识:TCP(博客:传送门),线程 附加:项目可能还有写不足之处,有些bug没调出来(如:对在线人数的控制),希望大佬赐教. 那么话不多说,放码过来: 码云:传送门, ...

  5. linux下C语言多线程编程实例

    用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...

  6. LINUX下C语言编程调用函数、链接头文件以及库文件

    LINUX下C语言编程经常需要链接其他函数,而其他函数一般都放在另外.c文件中,或者打包放在一个库文件里面,我需要在main函数中调用这些函数,主要有如下几种方法: 1.当需要调用函数的个数比较少时, ...

  7. Windows10下配置Linux下C语言开发环境

    今天为大家介绍如在Windows10下配置Linux下C语言开发环境,首先安装linux子系统:启用开发者模式 1.打开设置 2.点击更新和安全3.点击开发者选项 4.启用开发人员模式 5.更改系统功 ...

  8. linux 下C语言学习路线

    UNIX/Linux下C语言的学习路线.一.工具篇“公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工 ...

  9. Linux下C语言编程实现spwd函数

    Linux下C语言编程实现spwd函数 介绍 spwd函数 功能:显示当前目录路径 实现:通过编译执行该代码,可在终端中输出当前路径 代码实现 代码链接 代码托管链接:spwd.c 所需结构体.函数. ...

随机推荐

  1. 1. java 基本规则

    一.命名规范 1. 类名规范:首字母大写,后面每个单词首字母大写(大驼峰式),HelloWorld 2. 变量名规范:首字母小写,后面每个单词首字母大写(小驼峰式),helloWorld 3. 方法名 ...

  2. vue.config.json CopyWebpackPlugin 没有生效

    本地生效,服务器不生效. 因为是jenkinis构建,没有留意到报错.后来发现错误:ENOENT: no such file or directory, rename 解决方法就是:删除package ...

  3. React内容

    React Fiber   16版本 registerServiceWorker 的作用 PWA  progressive web application  写手机app应用   在断网的情况下,第二 ...

  4. bcftools

    beftools非常复杂,大概有20个命令,每个命令下面还有N多个参数 annotate .. edit VCF files, add or remove annotations call .. SN ...

  5. Java 发红包

    使用Java实现发红包的功能. 结构: package redPocket User.java Manager.java Member.java Demo.java 思路: Manager和Membe ...

  6. Dockerfile命令整理

    通过Dockerfile只做Docker镜像时,需要用到Dockerfile的命令,收集整理如下,以便后续翻阅参考. FROM 功能为指定基础镜像,并且必须是第一条指令. 如果不以任何镜像为基础,那么 ...

  7. golang基础之第一个go程序

    编写 Hello World 创建文件 hello.go,不写入任何内容.按照如下的命令尝试进行编译 $ go run hello.go 将会打印出如下错误: package main: hello. ...

  8. PHP自动加载-spl_autoload_register

    spl_autoload_register 自动加载spl : Standard PHP library (标准PHP库) 首先来了解 __autoload print.class.php <? ...

  9. 【VSFTP服务】vsftpd文件传输协议

    vsftpd文件传输协议 系统环境:CentOS Linux release 7.6.1810 (Core) 一.简介 FTP(文件传输协议)全称是:Very Secure FTP Server.   ...

  10. 为什么Linux 普通用户在虚拟机界面可以reboot 用ssh 不能reboot

    应该是有 类似的权限控制. 如果是 localhost , 那么普通用户允许重启. 如果不是localhost,  比如ssh远程的,必须验证root权限.