0

I wrote a c++ code to multithreaded copying a file to another directory in linux. but doesn't work(just it made an empty file in directory).

I don't know what's the problem? I think my tread has no right access to write in the shared file. but don't know what should I do.

It should work when typed in terminal :

$./a.out <file name> <dir> <thread number (default 4)>

This is my code:

/*Multithreads file copier*/

#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/sendfile.h>
#include <unistd.h>
#include <cstdio> 


char* file;
char* fileout_path;
int fin, fout;

// part of each thread
struct PART{
    off_t* offset =0;
    size_t size;
};

//multithreading 
void *Copy (void *  data)
{
    struct PART *mypart;
    mypart = (struct PART *) data;
//open file to read and write 
    fin = open(file, O_RDONLY,0);
    fout = open(fileout_path, O_WRONLY|O_CREAT, 0644);
    unsigned long a = static_cast<unsigned long>(mypart->size);
    lseek(fout, a, SEEK_SET); //set offset by size of the part
//use sendfile instead read and write to easier code
    sendfile(fin, fout, mypart->offset, mypart->size);
     printf("threading....\n");//to know the thread ran
     pthread_exit(0);
}



int main(int argc, char *argv[])
{
    int threads_number;
    if (argv[3]!= NULL)
    {
    threads_number = atoi(argv[3]);
    }
    else
    {
    threads_number = 4;//default thread number 
    }
//multithreading datatypes
    pthread_t tid[threads_number];
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    struct stat f_stat;
    struct PART part[threads_number];
    
//allocation size of each part
    unsigned long part_size = f_stat.st_size / threads_number;
   
    for(int i =0; i <number_threads; i++)
    {
        if ( i == threads_number -1)
        {
            part[threads_number].size = f_stat.st_size - (part_size * (threads_number -1));
        }
        else
        {
            part[i].size = part_size;
        }
      
        
    }
    
   
    
    
    file = argv[1];
    stat(file, &f_stat);    
    fileout_path = argv[2];

    
int fin1 = open(file, O_RDONLY,0);
    int fout1 = open(fileout_path, O_WRONLY|O_CREAT, 0644);
   
   
    for (int j = 0; j < threads_number; j++)
    {
        pthread_create(&tid[j], NULL, Copy, (void *)&part[j]);
        pthread_join(tid[j],NULL);
    }
 

        printf("thread is done.\n");
        close(fout);
        close(fin);

        return 0;
}


Zahra
  • 1
  • 2
  • 2
    I think this is pure `c` (despite ``) – apple apple Dec 05 '21 at 19:43
  • 2
    Note that by calling `pthread_join(tid[j], ...` immediately after `pthread_create(&tid[j], ...` you are effectively serializing the processing. – G.M. Dec 05 '21 at 19:54
  • 2
    You are using `f_stat.st_size` before calling `stat(&f_stat)` and the offset calculation also seem wrong. –  Dec 05 '21 at 19:59
  • 1
    Where do you assign any `part[i]->offset`? If you don't assign it, then you'll be passing a `NULL` pointer as the `offset` arg in `sendfile(...)`. Is that what you meant to do? – Solomon Slow Dec 05 '21 at 20:03
  • Also, if you compile the program with a C++ compiler (which you must do because of `#include `) Then you should not call `pthread_create(...)`. Use [`std::thread`](https://en.cppreference.com/w/cpp/thread) instead. – Solomon Slow Dec 05 '21 at 20:07

0 Answers0