2016-03-31 3 views
1

У меня есть следующий код, служащий основным контуром для сервера, который принимает входящие соединения сокетов.Ошибка сегментации в системном вызове accept

В настоящий момент макрос OperationMode определяется как 1, поэтому он выполнит логику pthread.

for (hit = 1 ;; hit++) { 
     printf("Got here\n\n"); 

     length = sizeof(cli_addr); 

     /* block waiting for clients */ 
     socketfd = accept(listenfd, (struct sockaddr *) &cli_addr, &length); 

     if (socketfd < 0) 
       printf("ERROR system call - accept error\n"); 
     else 
     { 
       printf("Testing\n\n\n"); 
       #ifdef OperationMode 
         pthread_t thread_id; 
         if(pthread_create(&thread_id, NULL, attendFTP(socketfd, hit), NULL)) 
         { 
           perror("could not create thread"); 
           return 1; 
         } 
       #else 
         pid = fork(); 
         if(pid==0) 
         { 
           ftp(socketfd, hit); 
         } 
         else 
         { 
           close(socketfd); 
           kill(pid, SIGCHLD); 
         } 
       #endif 
     } 
} 

Я смог создать поток для первого подключения входящего сокета, но когда я итерацию по петле я получаю ошибку сегментации ошибки в строке

socketfd = accept(listened, (struct sockaddr *) &cli_addr, &length); 

Моя функция attendFTP имеет следующий код

void *attendFTP(int fd, int hit) 
{ 
    ftp(fd, hit); 
    return NULL; 
} 

Это идеальное решение для реализации вилки. Как я могу исправить ошибку ошибки сегментации?

+0

Если 'attendFTP()' - функция, возвращающая указатель на функцию, вы используете 'pthread_create()' неправильно. – EOF

+0

@EOF Я добавил функцию 'attendFTP()'. Но я считаю, что правильно его использую. – rafaelcpalmeida

+0

Вы не используете его правильно. Прототипом является 'int pthread_create (pthread_t * thread, const pthread_attr_t * attr, void * (* start_routine) (void *), void * arg);'. Вам, вероятно, потребуется передать указатель на 'struct', если вам нужно несколько аргументов для функции, которую вы хотите выполнить нить. – EOF

ответ

1
pthread_create(&thread_id, NULL, attendFTP(socketfd, hit), NULL); 

Этот код passess результат вызова attendFTP() с заданным paramters - и этот результат всегда NULL.

Так что pthread_create пытается запустить функцию по адресу NULL и, соответственно, терпит неудачу.

Если вы запустите свой компилятор с аргументом -pedantic, компилятор скажет вам, что то, что вы делаете, неверно. Без -pedantic gcc допускает некоторые «расширения», которые могут скрыть ошибки. Кстати, вот почему -pedantic, на мой взгляд, обязательно.

Что вы на самом деле хотите, так это передать некоторые аргументы вашей функции потоковой передачи. К сожалению, он действительно запутан в C pthreads и требует, чтобы вы выделили и освободили упомянутый struct. Что-то вроде этого:

struct args { 
    int fd; 
    int hit; 
}; 
... 
pthread_t thread_id; 
struct args* args = malloc(sizeof(struct args)); 
args->fd = socketfd; 
args->hit = hit; 
if(pthread_create(&thread_id, NULL, attendFTP, args)) 
.... 

void* attendFTP(void* vargs) 
{ 
    struct args* args = vargs; 
    ftp(args->fd, args->hit); 
    free(args); 
    return NULL; 
} 
+0

Но первая итерация цикла выполняется успешно, не должна ли она потерпеть неудачу? – rafaelcpalmeida

+0

@rafaelcpalmeida, нет, это не так. Но поскольку вы вызываете attendFTP, вы в основном выполняете его в одном и том же потоке (без многопоточности) и видите некоторые результаты. Чем pthread создан и сбой приложения. – SergeyA

+0

Итак, первое вызов не является многопоточным? Как передать аргументы внутри функции attendFTP? Можете ли вы поделиться некоторым примером? Редактировать: Мне удалось заставить его работать с помощью структуры с аргументами, как сказал EOF. – rafaelcpalmeida

Смежные вопросы