2013-12-07 5 views
2

У меня вопрос о потоках C и их возвращаемом значении. Моя цель - найти все простые числа между начальным числом и конечным числом. У меня будет 4 потока, и каждая нить выполняет четверть диапазона.C нити и присоединение

Так, например, простые числа от 1 до 100.

  • нить 1 находит простые числа от 1 - 25
  • нить 2 26 - 50
  • нить 3 51 - 75
  • нить 4 76 - 100

Все простые числа будут храниться в массиве, и будет выполняться функция, которая вычисляет простые числа.

Мой вопрос, когда я присоединяюсь нити

pthread_join(tids[i], ptr); 

будет PTR быть указателем на объединенный массив всех простых чисел, 1 - 100?

Значение, если я использую цикл для печати значений

printf("%d", ptr[i]); 

он будет печатать все простые числа от 1 - 100, как один большой массив?

Я присоединяюсь к 4 отдельным массивам?

Спасибо

ответ

2

phtread_join() вернется через PTR, что соответствующий поток переходит к pthread_exit(). Каждый поток работает независимо и вычисляет собственный набор простых чисел, поэтому каждый поток должен создавать собственный массив и после того, как все потоки будут объединены, вы будете печатать результаты каждого массива. Для того, чтобы иметь возможность вернуть результирующий набор простых чисел и его счет, мы должны использовать собственный тип структуры:

struct comp_result { 
    unsigned *p_arr; 
    unsigned count; 
}; 

Я проиллюстрирую путь без блокировки:

compute_thread (...) { 
    ... 
    struct comp_result *p_res = malloc(sizeof(struct comp_result));   
    p_res->p_arr = NULL; 
    p_res->count = 0; 
    for (num = start; num < end; num++) { 
     if (is_prime(num)) { 
       p_res->count++; /// increment number of primes and expand our storage 
       p_res->p_arr = realloc(p_res->p_arr, p_res->count*sizeof(int)); 
       p_res->p_arr[p_res->count-1] = num; // save prime in result array 
     } 
    } 

    // pass pointer to per-thread result data 
    pthread_exit(p_res); 
} 


main() { 
     .... // create threads 
     .... 
     for (i = 0; i < num_of_threads; i++) { 
      struct comp_result *p_res; 
      // retrieve and print array from i-thread 
      pthread_join(tids[i], &p_res); 
      for (num = 0; num < p_res->count; num++) { 
       printf(" %d ", p_res->p_arr[num]); 
      } 
      free(p_res->p_arr); 
      free(p_res); 
     } 
} 

Иллюстрация с блокировкой необходим еще один struct type, так как мы передадим указатель на результат обмена данными в каждом потоке:

struct control { 
    unsigned start; 
    unsigned end; 
    struct comp_result *p_res; 
} 

compute_thread (ptr) { 
    struct control *p_cont = (struct control*)ptr; 
    // retrieve the pointer to shared, but be accurate with it! 
    struct comp_result *p_res = p_cont->p_res; 

    // initialize lock 
    pthread_mutex_init(&p_res->lock, NULL); 

    ... 
    for (num = p_cont->start; num < p_cont->end; num++) { 
     if (is_prime(num)) { 
       pthread_mutex_lock(&p_control->lock); 
       // modify shared data with locking 
       p_res->count++; /// increment number of primes and expand our storage 
       p_res->p_arr = realloc(p_res->p_arr, p_res->count*sizeof(int)); 
       p_res->p_arr[p_res->count-1] = num; // save prime in result array 
       pthread_mutex_unlock(&p_control->lock); 
     } 
    } 

    pthread_exit(NULL); 
} 


main() { 
     //create one shared data and initialize it: 
     struct comp_result *p_res = malloc(sizeof(struct comp_result));   

     p_res->p_arr = NULL; 
     p_res->count = 0; 

     for (i = 0; i < num_of_threads; i++) { 
      // create per-thread control data: 
      struct control *p_control = malloc(sizeof(struct control));   
      p_control->start = 
      p_control->end = 
      p_control->p_res = p_res; 
      pthread_crate(&tids[i], NULL, compute_thread, p_control); 
     } 
     .... 
     for (i = 0; i < num_of_threads; i+++) { 
      pthread_join(tids[i], NULL); 
     } 
     // now all threads are completed and we are ready to read result: 
     for (num = 0; num < p_res->count; num++) { 
      printf(" %d ", p_res->p_arr[num]); 
     } 
} 
+0

Хорошо, спасибо. А также я могу объявить пустоту * ptr = NULL; а затем в моей функции соединения do pthread_join (tids [i], &ptr); Будет ли это работать? – user2817240

+0

Итак, в этом случае ptr - это переменная, которая указывает на массив. Поэтому я могу использовать цикл for, нанести указатель на мою структуру типа и печатать простые числа в массиве? – user2817240

+0

Так как у меня будет 4 массива, могу ли я использовать переменную ptr и сделать один массив и вернуть это? – user2817240

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