2015-04-12 3 views
0

У меня возникла странная проблема с созданием потоков через цикл. У меня есть массив потоков, и пользователь может указать количество потоков от 1 до 25. Конкретная проблема, с которой я столкнулся, - это получение ошибки seg при прохождении и объединении отдельных потоков в массиве потоков. Я отлаживал его и видел, что значения потоков в массиве распространяются спорадически. Например, если пользователь указал 9 потоков и массив имеет 25 возможных нитей общего, то массив будет выглядеть примерно так:Создание и объединение pthreads в цикле

{0, 0, 12332342, 0, 0, 123212313, ...} 

В основном, заселенные индексы не от индекса 0 до 9, как и ожидалось, но скорее распространяется по всему массиву.

Мой код немного грязный, поэтому я только включил соответствующий раздел, пожалуйста, дайте мне знать, если больше контекста требуется:

int max_chld_threads = p_args->num_threads - 1; 
int chld_threads_delay = p_args->cons_chld_delay; 
pthread_t chld_threads[25]; 
consargs chld_c_args[25]; 
char chld_name[2] = {'B', 0}; 
int thd_cnt = 0; 
size_t max_char = MAX_CHAR_PER_LINE - 1; 
char term_sentinel[] = "@$%#"; 
int i; 
char *cur_file; 
char *line; 
void *retval; 

if ((line = (char *) malloc(max_char * sizeof(char))) == NULL) { 
    perror("Malloc failed"); 
    exit(1); 
} 

//Opening files in file array 
for (i = 0; i < num_files; i++) { 
    cur_file = *(file_path_lst + i); 
    if ((fp = fopen(cur_file, "r")) == NULL) { 
     perror("Cannot open"); 
     continue; 
    } 
    while (getline(&line, &max_char, fp) != -1) { 
     put (&buffer, line); 

     //Creates new child thread if buffer is full 
     if (thd_cnt < max_chld_threads && buffer.full == 1) { 

      //Copies the argument which contains a thread's name 
      strncpy(chld_c_args[thd_cnt].name, chld_name, sizeof(chld_c_args)); 
      chld_c_args[thd_cnt].delay = chld_threads_delay; 

      if (pthread_create (&chld_threads[thd_cnt], NULL, consumer, 
           (void *) &chld_c_args[thd_cnt]) != 0) { 
       perror("Child consumer thread creation failed"); 
       continue; 
      } 

      //Increment the letter for next child thread 
      chld_name[0]++; 
      thd_cnt++; 
     } 
    } 
    fclose(fp); 
} 
put (&buffer, term_sentinel); 
/* Join here */ 
for (i = 0; i < thd_cnt; i++) { //SEGFAULTS here 
    pthread_join (chld_threads[i], &retval); 
} 

consargs:

struct consargs 
{ 
    int delay; 
    char name[2]; 
}; 
+0

Как определяется «consargs»? – alk

+1

Loop 'int max_chld_threads = p_args-> num_threads - 1;' times и задание массивов с использованием константы '25' является опасным. Не хорошо. – alk

+0

@alk, извините за поздний ответ. Я разместил код для 'consargs'. – mrQWERTY

ответ

1

Не уверен, если это вызывает определенную проблему, но у вас, вероятно, есть переполнение буфера в этой строке:

strncpy(chld_c_args[thd_cnt].name, chld_name, sizeof(chld_c_args)); 

Это должно be:

strncpy(chld_c_args[thd_cnt].name, chld_name, 
     sizeof(chld_c_args[thd_cnt].name)); 

strncpy будет наносить удары нулями. Таким образом, вы, вероятно, перезаписываете thd_cnt (и другие переменные).

+1

Зачем использовать уязвимость 'strncpy()', а не просто 'strcpy()'? – alk

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