Читаем Программирование для 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++).

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

Если второй аргумент функции 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.2
1С: Управление торговлей 8.2

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

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

Финансы / Программирование, программы, базы данных
Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С
Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С

В книге последовательно рассматриваются все этапы создания встраиваемых систем на микроконтроллерах с применением современных технологий проектирования. Задумав эту книгу, авторы поставили перед собой задачу научить читателя искусству создания реальных устройств управления на однокристальных микроконтроллерах. Издание содержит материал, охватывающий все вопросы проектирования, включает множество заданий для самостоятельной работы, примеры программирования, примеры аппаратных решений и эксперименты по исследованию работы различных подсистем микроконтроллеров. Данная книга является прекрасным учебным пособием для студентов старших курсов технических университетов, которые предполагают связать свою профессиональную деятельность с проектированием и внедрением встраиваемых микропроцессорных систем. Книга также будет полезна разработчикам радиоэлектронной аппаратуры на микроконтроллерах.

Дэниэл Дж. Пак , Стивен Ф. Барретт

Программирование, программы, базы данных / Компьютерное «железо» / Программирование / Книги по IT