Ошибка: Seg. Ошибка. Хотите скопировать несколько файлов с использованием многопоточности

#c #multithreading #pthreads #file-handling

#c #многопоточность #pthreads #обработка файлов

Вопрос:

****** РЕШАЕМАЯ ******

Я хотел скопировать несколько файлов с использованием многопоточности. Это заканчивается ошибкой: ошибка сегментации. Не могу определить, где.

Что я пробовал: print("test"); в разных строках, но выдает ту же ошибку. Я думаю, что основная функция верна, что-то в start_routine() блоке.

Код:

 typedef struct filePair
{
    char srcName[100];
    char dstName[100];
} filePair;

void * start_routine(void *arg) //file handling using system calls
{
    char tmp;

    printf("Copying %s to %s.n", ((filePair *)arg)->srcName, ((filePair *)arg)->dstName);

    int src = open(((filePair *)arg)->srcName, O_RDWR); //open source file
    if (!src)
    {
        printf("Cannot open source file.n"); //error handling
        exit(0);
    }

    //open dst file
    int dst = open(((filePair *)arg)->dstName, O_WRONLY | O_CREAT, 0641);
    if (!dst)
    {
        printf("Error in destination file.n"); //error handling
        exit(0);
    }

    while (read(src, amp;tmp, 1)) //while loop to copy contents
        write(dst, amp;tmp, 1);

    close(src); //close src and dst files
    close(dst);

    return NULL;
}

//main function...
 

Комментарии:

1. Правильный тип struct filePair * .

2. @kaylum так что каждый раз, когда я выполняю (filePair*) это, должно быть (struct filePair*) ?

3. Необходимо использовать скобки, поскольку -> имеет более высокий приоритет, чем приведение. ((struct filePair *)arg)->src . Но это упростит код для создания переменной и выполнения приведения один раз в начале функции: struct filePair *fpair = (struct filePair *) arg;

4. @kaylum Я пробовал это, выдает ошибку сегментации

5. Это потому, что в вашем коде есть другие ошибки. struct filePair * file1; strcpy(file1->src, "file1.dat"); Не могу делать подобные вещи. file1 недопустимый указатель, и его нельзя разыменовывать. Сделайте вместо: struct filePair file1; strcpy(file1.src, "file1.dat");

Ответ №1:

Имя типа struct filePair . Распространенный способ сократить использование типа — включить typedef :

 typedef struct
{
    char src[100];
    char dst[100];
} filePair;
 

Затем вы можете обратиться к типу. filePair

Комментарии:

1. Большое вам спасибо!

Ответ №2:

1. причиной ошибки сегментации в коде является неправильное использование указателей. создание указателей типа filePair и не выделение достаточного объема памяти для этих указателей приведет к ошибке сегментации. Если мы выделим достаточно памяти для этих указателей, это больше не будет проблемой.

  1. прототип для pthread_create()

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

перед передачей *file1 в pthread_create() мы должны придать указателю file1 тип (void *).

Здесь я предоставляю простую версию без использования указателей для filePair, но вместо этого использую экземпляры filePair.

 #include <stdio.h>     /* printf, stderr */
#include <sys/types.h> /* pid_t */
#include <unistd.h>    /* fork */
#include <stdlib.h>    /* atoi */
#include <errno.h>     /* errno */
#include <pthread.h>   /* pthread */
#include <sys/stat.h>
#include <fcntl.h> /* file handling */
#include <time.h>  /* CLOCK */
#include <string.h>

typedef struct
{
    char srcName[100];
    char dstName[100];
} filePair;

void * start_routine(void *arg) //file handling using system calls
{
    char tmp;

    printf("Copying %s to %s.n", ((filePair *)arg)->srcName, ((filePair *)arg)->dstName);

    int src = open(((filePair *)arg)->srcName, O_RDWR); //open source file
    if (!src)
    {
        printf("Cannot open source file.n"); //error handling
        exit(0);
    }

    //open dst file
    int dst = open(((filePair *)arg)->dstName, O_WRONLY | O_CREAT, 0641);
    if (!dst)
    {
        printf("Error in destination file.n"); //error handling
        exit(0);
    }

    while (read(src, amp;tmp, 1)) //while loop to copy contents
        write(dst, amp;tmp, 1);

    close(src); //close src and dst files
    close(dst);

    return NULL;
}


/* main function */
int main(int argc, char *argv[])
{
    pthread_t thread1; //Threads init
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
    pthread_t thread5;

    filePair  file1;
    strcpy(file1.srcName, "file1.dat");
    strcpy(file1.dstName, "copy1.dat");

    filePair  file2;
    strcpy(file2.srcName, "file2.dat");
    strcpy(file2.dstName, "copy2.dat");

    filePair  file3;
    strcpy(file3.srcName, "file3.dat");
    strcpy(file3.dstName, "copy3.dat");

    filePair  file4;
    strcpy(file4.srcName, "file4.dat");
    strcpy(file4.dstName, "copy4.dat");

    filePair  file5;
    strcpy(file5.srcName, "file5.dat");
    strcpy(file5.dstName, "copy5.dat");

    printf("n Before threading.nn");

    //Creating threads
    pthread_create(amp;thread1, NULL, start_routine, (void *)amp;file1);
    pthread_create(amp;thread2, NULL, start_routine, (void *)amp;file2);
    pthread_create(amp;thread3, NULL, start_routine, (void *)amp;file3);
    pthread_create(amp;thread4, NULL, start_routine, (void *)amp;file4);
    pthread_create(amp;thread5, NULL, start_routine, (void *)amp;file5);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_join(thread3, NULL);
    pthread_join(thread4, NULL);
    pthread_join(thread5, NULL);

    printf("n After threading.nn");

    return 0;
}