(Linux_C)多线程拷贝文件

如果代码难理解,欢迎多交流一下

实现功能

多线程拷贝命令,如:./my_cp srcfile destfile N(拷贝线程个数)

  1. mmap将磁盘文件映射到内存空间
  2. pthread_create创建线程
  3. pthread_detach将子线程分离,好处:线程不需在主线程中pthread_join进行阻塞回收资源,子线程结束后由系统自动回收。
  4. Info为自定义结构体,用于线程调用函数的传参,参数包括文件大小、srcfile的内存地址指针、descfile的内存地址指针、最大线程数以及当前为第几个线程标志。

Info描述符(结构体)

// An highlighted block
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void sys_err(char *str)
{
	perror(str);
	exit(1);
}

typedef struct Info{
	int maxnum;//最大线程数
	int num;//表示第几个线程
	char *sc_addr,*desc_addr;//映射后的地址
	int size;//每个线程拷贝的大小
	int filesize;//文件大小
}Info;

void *thr_fn(void *arg)
{
	if(arg == NULL)
		sys_err("arg");
	//接收参数
	Info *accept = (Info *)arg;
	printf("pthread %d is copying\n",accept->num);
	//根据每个线程中Num成员得不同的偏移量
	char offset = accept->num * accept->size;
	if(accept->num < accept->maxnum-1)
		memcpy(accept->desc_addr + offset,accept->sc_addr + offset,\
				(size_t)accept->size);
	else{
	/*因为filesize/num不可能整除,所有最后一个线程需特殊处理,拷贝剩余字节,
	文件总大小注意maxnum要减一,因为线程个数是从1开始,而编号是从0开始。*/
		memcpy(accept->desc_addr + offset,accept->sc_addr + offset,\
		(size_t)(accept->filesize - (accept->maxnum-1) * accept->size));
	}
}

int main(int argc,char *argv[])
{
	pthread_t tid;
	Info *info;
	unsigned char i;
	//注意区分num 和 info->num。
	int num = atoi(argv[3]);

	info = (Info *)malloc(num * sizeof(Info));
	memset(info,0,num * sizeof(Info));

	int sc_fd = open(argv[1],O_RDONLY);
	umask(0);
	int desc_fd = open(argv[2],O_RDWR | O_CREAT,0777);

	info[0].maxnum = num;
	//通过lseek指定目标文件的大小与源文件大小一样
	info[0].filesize = lseek(sc_fd,0,SEEK_END);
	ftruncate(desc_fd,info[0].filesize);
	//这里提醒一下,5个线程对应的Info结构体参数只有num成员不同,其它均一样。
	info[0].size = info[0].filesize / num + (info[0].filesize % num >0? 1:0);
	
	info[0].sc_addr = (char *)mmap(NULL, (size_t)info[0].filesize, \
			PROT_READ,MAP_SHARED, sc_fd,0);
	info[0].desc_addr = (char *)mmap(NULL, (size_t)info[0].filesize,\
	 PROT_READ | PROT_WRITE,MAP_SHARED, desc_fd, 0);
	for(i = 1;i<5;i++){
		info[i] = info[0];
	}
	while(num--){
		info[num].num = num;
		pthread_create(&tid,NULL,thr_fn,(void *)&info[num]);
		//分离线程
		pthread_detach(tid);
	}
	printf("main thread ending!\n");
	pthread_exit(NULL);
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值