实现多线程拷贝命令,如:./multithread_copy srcfile destfile N(拷贝线程个数)
难点:
内存映射mmap。
给每一个线程合理的分配任务。
多线程的实现。
具体的实现代码如下:
/*********************************
> File Name: multithread_copy.c
> Author: lucifer
> Mail: lucifer@163.com
*********************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
#define N 5
int nthread = 0;
struct allocate_task
{
char *start;
char *end;
int size;
int num;
};
void sys_err(const char *str)
{
perror(str);
exit(-1);
}
void *thread_copy(void *arg)
{
int i;
struct allocate_task *s = (struct allocate_task *)arg;
for(i = 0;i < nthread;i++)
{
memcpy(s[i].end,s[i].start,s[i].size);
}
}
int main(int argc, char *argv[])
{
int fdsrc, fddest, i, err, total_size,task_size;
struct stat sbuf;
char *psrc,*pdest;
if(argc < 3)
{
fprintf(stdout,"%s srcname destname\n",argv[0]);
exit(-1);
}
if(argc = 3)
nthread = N;
else
nthread = atoi(argv[3]);
if(stat(argv[1],&sbuf) < 0)
sys_err("stat");
total_size = sbuf.st_size;
fddest = open(argv[2],O_CREAT |O_RDWR | O_TRUNC,0664);
if(fddest < 0)
sys_err("open");
if(lseek(fddest,total_size - 1,SEEK_SET) < 0)
sys_err("lseek");
write(fddest,"\0",1);
fdsrc = open(argv[1],O_RDONLY);
if(fdsrc < 0)
sys_err("open");
psrc = mmap(NULL,total_size,PROT_READ,MAP_PRIVATE,fdsrc,0);
if(psrc == MAP_FAILED)
sys_err("mmap");
pdest = mmap(NULL,total_size,PROT_WRITE,MAP_SHARED,fddest,0);
if(pdest == MAP_FAILED)
sys_err("mmap");
close(fdsrc);
close(fddest);
struct allocate_task *work = malloc(nthread * sizeof(struct allocate_task));
task_size = total_size / nthread;
for(i = 0;i < nthread - 1;i++)
{
work[i].start = psrc + i * task_size;
work[i].end = pdest + i * task_size;
work[i].size = task_size;
}
work[i].start = psrc + i * task_size;
work[i].end = pdest + i * task_size;
work[i].size = total_size - task_size * (nthread - 1);
work[i].num = i;
pthread_t tid[nthread];
for(i = 0;i < nthread;i++)
{
err = pthread_create(&tid[i],NULL,thread_copy,(void *)work);
if(err != 0)
{
printf("%s\n",strerror(err));
break;
}
}
for(i = 0;i < nthread; i++)
{
pthread_join(tid[i],NULL);
}
free(work);
return 0;
}
本文永久更新地址://m.ajphoenix.com/linux/21964.html