转自: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. 【洛谷P4251】[SCOI2015]小凸玩矩阵(二分+二分图匹配)

    洛谷 题意: 给出一个\(n*m\)的矩阵\(A\).现要从中选出\(n\)个数,任意两个数不能在同一行或者同一列. 现在问选出的\(n\)个数中第\(k\)大的数的最小值是多少. 思路: 显然二分一 ...

  2. jQuery中的属性(四)

    1. attr(name|properties|key,value|fn), 设置或返回被选元素的属性值 参数说明: name:属性名称 properties:作为属性的“名/值对”对象 key,va ...

  3. 《Verilog数字系统设计教程(第2版).pdf》

    Verilog数字系统设计教程(第2版).pdf https://github.com/shigh1005/pdf_book <Linux设备驱动开发详解:基于最新的Linux 4.0内核.pd ...

  4. luoguP2178 [NOI2015]品酒大会(后缀自动机)

    题意 承接上篇题解 考虑两个后缀的\(lcp\)是什么,是将串反着插入后缀自动机后两个前缀(终止节点)的\(lca\)!!!于是可以在parent tree上DP了. 比后缀数组又简单又好写跑的还快. ...

  5. 【BZOJ3876】[AHOI2014&JSOI2014] 支线剧情(无源汇有上下界网络流)

    点此看题面 大致题意: 有一张\(DAG\),经过每条边有一定时间,从\(1\)号点出发,随时可以返回\(1\)号点,求经过所有边的最短时间. 无源汇有上下界网络流 这是无源汇有上下界网络流的板子题. ...

  6. AutoDesk公司搞的fbx模型格式

    FBX® data exchange technology is a 3D asset exchange format that facilitates higher-fidelity data ex ...

  7. npm和yarn的区别,我们该如何选择?

    首先,这两个都属于js包管理工具,都可以安装包或者模块yarn 是由facebook.google等联合开发推出的区别: npm 下载包的话 比如npm install它是按照包的排序,也就是队列挨个 ...

  8. javascript模块化编程的cmd规范(sea.js)

    CMD(Common Module Definition,通用模块定义)是一种模块定义规范,规范中明确了模块的基本书写格式和基本交互规则.SeaJS就是遵循的这个规范. define函数 在CMD规范 ...

  9. Vue.js安装及环境搭建

    Vue.js环境搭建-Windows版 步骤一:安装node.js 在搭建vue的开发环境之前,需要先下载node.js,vue的运行是要依赖于node的npm的管理工具来实现,node可以在官网或者 ...

  10. 2019-9-2-win10-uwp-判断本地ip

    原文:2019-9-2-win10-uwp-判断本地ip title author date CreateTime categories win10 uwp 判断本地ip lindexi 2019-0 ...