4.1.3. Значения, возвращаемые потоками

We use cookies. Read the Privacy and Cookie Policy

4.1.3. Значения, возвращаемые потоками

Если второй аргумент функции pthread_join() не равен NULL, то в него помещается значение, возвращаемое потоком. Как и потоковый аргумент, это значение имеет тип void*. Если поток возвращает обычное число типа int, его можно свободно привести к типу void*, а затем выполнить обратное преобразование по завершении функции pthread_join().[13]

Программа, представленная в листинге 4.4, в отдельном потоке вычисляет n-е простое число и возвращает его в программу. Тем временем функция main() может продолжать свои собственные вычисления. Сразу признаемся: алгоритм последовательного деления, используемый в функции compute_prime(), весьма неэффективен. В книгах по численным методам описаны более мощные алгоритмы (например, "решето Эратосфена").

Листинг 4.4. (primes.с) Вычисление простых чисел в потоке

#include <pthread.h>

#include <stdio.h>

/* Находим простое число с порядковым номером N, где N -- это

   значение, на которое указывает параметр ARG. */

void* compute_prime(void* arg) {

 int candidate = 2;

 int n = *((int*)arg);

 while (1) {

  int factor;

  int is_prime = 1;

  /* Проверка простого числа путем последовательного деления. */

  for (factor = 2; factor < candidate; ++factor)

   if (candidate % factor == 0) {

    is_prime = 0;

    break;

   }

  /* Это то простое число, которое нам нужно? */

  if (is_prime) {

   if (--n == 0)

    /* Возвращаем найденное число в программу. */

    return (void*)candidate;

  }

  ++candidate;

 }

 return NULL;

}

int main() {

 pthread_t thread;

 int which_prime = 5000;

 int prime;

 /* Запускаем поток, вычисляющий 5000-е простое число. */

 pthread_create(&thread, NULL, &compute_prime, &which_prime);

 /* Выполняем другие действия. */

 /* Дожидаемся завершения потока и принимаем возвращаемое им

    значение. */

 pthread_join(thread, (void*)&prime);

 /* Отображаем вычисленный результат. */

 printf("The %dth prime number is %d. ", which_prime, prime);

 return 0;

}