Читаем Программирование для Linux. Профессиональный подход полностью

В листинге 4.3 приведена исправленная версия функции main() из предыдущего, неправильного примера. В данном случае функция main() не завершается, пока оба дочерних потока не выполнят свои задания и не перестанут ссылаться на переданные им структуры.

Листинг 4.3. Исправленная функция main() из файла thread-create.c

int main() {

 pthread_t thread1_id;

 pthread_t thread2_id;

 struct char_print_parms thread1_args;

 struct char_print_parms thread2_args;

 /* Создание нового потока, отображающего 30000

    символов 'x'. */

 thread1_args.character = 'x';

 thread1_args.count = 30000;

 pthread_create(&thread1_id, NULL, &char_print, &thread1_args);

 /* Создание нового потока, отображающего

    20000 символов 'o'. */

 thread2_args.character = 'o';

 thread2_args.count = 20000;

 pthread_create(&thread2_id, NULL, &char_print, &thread2_args);

 /* Убеждаемся, что завершился первый поток. */

 pthread_join(thread1_id, NULL);

 /* Убеждаемся, что завершился второй поток. */

 pthread_join(thread2_id, NULL);

 /* Теперь можно спокойно завершать работу. */

 return 0;

}

Мораль сей басни такова: убедитесь, что любые данные, переданные потоку по ссылке, не удаляются (даже другим потоком) до тех пор, пока поток не завершит свою работу с ними. Это относится как к локальным переменным, удаляемым автоматически при выходе за пределы своей области видимости, так и к динамическим переменным, удаляемым с помощью функции free() (или оператора delete в C++).

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

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

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

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

#include

#include

/* Находим простое число с порядковым номером 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*)′);

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

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных