多线程拷贝

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

#define T_NUM 5
#define ITEMS 50

void err_sys(void *str)
{
    perror(str);
    exit(1);
}

void err_usr(char *str)
{
    fputs(str, stderr);
    exit(1);
}

typedef struct{
    int off, size, t_no;
}arg_t;

char *s, *d;
int *done;
int n = T_NUM;

//arg{off, size, t_no;}
void *tfn(void *arg)
{
    arg_t *arg_p; int i;
    char *p, *q;

    arg_p = (arg_t *)arg;
    p = s + arg_p->off, q = d + arg_p->off;
    for(i = 0; i < arg_p->size; i++)
    {
        /* 逗号表达式的使用技巧*/
        *q++ = *p++, done[arg_p->t_no]++;
        usleep(5000);
    }

    return NULL;
}

void *display(void *arg)
{
    int size, interval, draw, sum, i, j;

    size = (int)arg;
    interval = size / (ITEMS - 1);
    draw = 0;
    while(draw < ITEMS){
        for(i = 0, sum = 0; i < n; i++)
            sum += done[i];
        j = sum / interval + 1;
        for(; j > draw; draw++){
            putchar('='); fflush(stdout);
        }
    }
    putchar('\n');

    return NULL;
}

int main(int argc, char *argv[])
{
    int src, dst, i, len, off;
    struct stat statbuf;
    pthread_t *tid;
    arg_t *arr;

    if(argc != 3 && argc != 4)
        err_usr("usage : cp src dst [thread_no]\n");
    if(argc == 4)
        n = atoi(argv[3]);

    src = open(argv[1], O_RDONLY);
    if(src == -1)
        err_sys("fail to open");
    dst = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0644);
    if(dst == -1)
        err_sys("fail to open");

    if(fstat(src, &statbuf) == -1)
        err_sys("fail to stat");

    lseek(dst, statbuf.st_size - 1, SEEK_SET);
    write(dst, "a", 1);

    s = (char *)mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, src, 0);
    if(s == MAP_FAILED)
        err_sys("fail to mmap");
    d = (char *)mmap(NULL, statbuf.st_size, PROT_WRITE , MAP_SHARED, dst, 0);
    if(d == MAP_FAILED)
        err_sys("fail to mmap");
    close(src); close(dst);
    //pthread_t tid[n+1];
    tid = (pthread_t *)malloc(sizeof(pthread_t) * (n + 1));
    if(tid == NULL)
        err_sys("fail to malloc");
    done = (int *)calloc(sizeof(int), n);
    if(done == NULL)
        err_sys("fail to malloc");
    arr = (arg_t *)malloc(sizeof(arg_t) * n);
    if(arr == NULL)
        err_sys("fail to malloc");

    len = statbuf.st_size / n, off = 0;
    for(i = 0; i < n; i++, off += len) 
        arr[i].off = off, arr[i].size = len, arr[i].t_no = i; 
    arr[n - 1].size += (statbuf.st_size % n);
    for(i = 0; i < n; i++)
        pthread_create(&tid[i], NULL, tfn, (void *)&arr[i]);

    pthread_create(&tid[n], NULL, display, (void *)statbuf.st_size);

    for(i = 0; i < n + 1; i++)
        pthread_join(tid[i], NULL);
#if 1 
    munmap(s, statbuf.st_size);
    munmap(d, statbuf.st_size);
#endif
    free(tid); free(done); free(arr);

    return 0;
}



//////////////////////////////////////////////////////////
//自己的
#include<stdio.h>
#include<sys/mman.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#define Sun 5
#define DEF 1024*1024
typedef struct Date
{

    char* r_begin;
    char* w_begin;
    int size;
}data;
int fid,mid,rid;
int count;
long long num;
char *witeid;
char *readid;
pthread_mutex_t mutex;
void sys_error(char* str)
{
    perror(str);
    exit(1);
}
void *mycapy(void * arg)
{
    char* buf= (char*)malloc(sizeof(char));
    int n;
    int i =0;
    struct Date *dt = (struct Date*)arg;
    char* readf = dt->r_begin;
    char* writef = dt->w_begin;
    for(i;i<dt->size;i++)
    {
        strncpy(buf,readf,1);
        *writef=*buf;
        pthread_mutex_lock(&mutex);
        count++;
        pthread_mutex_unlock(&mutex);
        readf++;
        writef++;


    }
    free(dt);
    free(buf);
    return(void*)0;
}

void Mypthreadcreate(int sum,int yu,int sleek)
{
    int i;
    pthread_t *pid =(pthread_t*) malloc(sizeof(pthread_t)*sum);
// pthread_t pid ;
    for(i=0;i<sum;i++)
    {
        struct Date *da =(struct Date*)malloc(sizeof(struct Date));
        if(i==sum-1)
            da->size = sleek+yu;
        else
            da->size = sleek;
        da->r_begin = readid + i*sleek;
        da->w_begin = witeid + i*sleek;
        int clt =pthread_create(&pid[i],NULL,mycapy,(void*)da);
// int clt =pthread_create(&pid,NULL,mycapy,(void*)da);
        if(clt!=0)
        {
            printf("pthread_cread error %s\n",strerror(clt));
        }
    }
    int k;
    for(k=0;k<sum;k++)
    {
        pthread_join(pid[k],NULL);
    }

    free(pid);
}
void Mymmap(int sum,int sleek,int n ,int yuy, int yu)
{
    int ii =0;
    for(ii;ii<n;ii++)
    {
        int NUM = DEF;
        int NM = DEF;
        if(num<DEF)
            NUM = num;
        NM = NM*ii;
        if(ii==(n-1))
            NUM = NUM+yuy;
        readid =(char*) mmap(NULL,NUM,PROT_READ, MAP_SHARED,fid,NM);
        if(readid==MAP_FAILED)
        {
            sys_error("mmap readid error");
        }
        witeid= (char*)mmap(NULL,NUM,PROT_WRITE,MAP_SHARED,rid,NM);
        if(witeid==MAP_FAILED)
        {
            sys_error("mmap witeid error");
        }
        printf("wr %d\n",ii);
        Mypthreadcreate(sum,yu,sleek);      
        munmap(readid,NUM);
        munmap(witeid,NUM);
    }
}
int main(int argv,char* argc[])
{ 
    int i;
    int sleek;
    int  sum;
    int yu;

    if(argv<3)
    {
        printf("input like ./mycpy oldfile newfile");
        return 0;
    }




    fid = open(argc[1],O_RDONLY);
    if(fid<0)
    {
        sys_error("open readfile error");
    }
     num = lseek(fid,0,SEEK_END);
    rid = open(argc[2],O_RDWR|O_CREAT,0777);
    if(rid<0)
    {
        sys_error("open witefile error");
    }
    long long  ret = ftruncate(rid,num);
    if(ret<0)
    {
        sys_error("ftruncate error");
    }





    if(num <= DEF)
    {
        if(argv==4)
        {   int mm =atoi(argc[3]);
            yu = num%mm;
            sleek = num/mm;
            sum = mm;
        }
        else
        {
            sleek = num/Sun;
            sum = Sun;
            yu = num%Sun;
        }
        Mymmap(sum,sleek,1,0,yu);
        printf("r %d\n",999);
    }
    else if(num>DEF)
    {
        int NUM = DEF;
        int yuy = num%NUM;
        int n = num/NUM;
        int ii =0;
printf("n = %d\n",n);
        if(argv==4)
        {   int mm =atoi(argc[3]);
            yu = NUM%mm;
            sleek = NUM/mm;
            sum = mm;
        }
        else
        {
            sleek = NUM/Sun;
            sum = Sun;
            yu = NUM%Sun;
        }
        Mymmap(sum,sleek,n,yuy,yu);
    }



    close(fid);

    sleep(2);
    return 0;
}




你可能感兴趣的:(多线程拷贝)