#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 и не выделение достаточного объема памяти для этих указателей приведет к ошибке сегментации. Если мы выделим достаточно памяти для этих указателей, это больше не будет проблемой.
- прототип для 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;
}