转自: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. HTML&CSS基础-子元素和后代元素选择器

    HTML&CSS基础-子元素和后代元素选择器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.html源代码 <!DOCTYPE html> <html ...

  2. Node.js—基本知识

    一.第一个Node代码 1. 运行Node.js   通过node E:\Node代码\hello.js运行代码:Node.js是服务器的程序,写的js语句都将运行在服务器上.返回给客户的,都是已经处 ...

  3. 并发编程学习笔记(七、Thread源码分析)

    目录: 常见属性 构造函数 start() run() 常见属性: /** * 线程名称 */ private volatile String name; /** * 线程优先级 */ private ...

  4. Pwn-level1

    题目地址 https://dn.jarvisoj.com/challengefiles/level1.80eacdcd51aca92af7749d96efad7fb5 先看一下文件的类型和保护机制   ...

  5. shell的几个实战脚本例子(欠)

    如何让shell实现 可选择性执行 的功能 巡检内存使用率 批量创建用户 场景:公司想要做测试,需要10000个用户 数据库里查询学生成绩 #如何登录mysql数据库 #如何写sql对数据进行操作 # ...

  6. sqlserver deadlock

    当时系统测试的时候,由于使用了自动化测试跑脚本,一下子出了很多sqlserver deadlock的问题. 都处于system test阶段了,哪儿还有时间仔细分析这些死锁是怎么出来的,直接上retr ...

  7. Note | PyTorch

    目录 0. 教程和笔记 1. 模型操作 2. 网络设计 卷积图示 填充(padding) 升采样 全连接层 3. 损失函数 交叉熵 4. 系统或环境交互 模型加载 5. 犯过的错误 损失异常 测试显存 ...

  8. [NewLife.XCode]导入导出(实体对象百变魔君)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...

  9. java.util.concurrent各组件分析 一 sun.misc.Unsafe

    java.util.concurrent各组件分析 一 sun.misc.Unsafe 说到concurrent包也叫并发包,该包下主要是线程操作,方便的进行并发编程,提到并发那么锁自然是不可缺少的, ...

  10. 在Ubuntu18.04.2LTS上安装搜狗输入法

    在Ubuntu18.04.2LTS上安装搜狗输入法 一.前言 最近项目使用到了Linux系统,因此就安装了Ubuntu18.04.2这个最新的LTS的OS.整体的使用效果是不敢恭维的,特别是使用虚拟机 ...