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

    семафора, один из них будет разблокирован и

    обработает задание. */

 sem_post(&job_queue_count);


 /* Освобождаем исключающий семафор. */

 pthread_mutex_unlock(&job_queue_mutex);

}

Прежде чем извлекать задание из очереди, каждый поток дожидается семафора. Если счетчик семафора равен нулю, т.е. очередь пуста, поток блокируется до тех пор, пока в очереди не появится новое задание и счетчик не станет положительным.

Функция enqueue_job() добавляет новое задание в очередь. Подобно потоковой функции, она захватывает исключающий семафор, перед тем как обратиться к очереди. После добавления задания функция enqueue_job() устанавливает семафор, сообщая потокам о том, что задание доступно. В программе, показанной в листинге 4.12, потоки никогда не завершаются: если задания не поступают в течение длительного времени, все потоки переводятся в режим блокирования функцией

sem_wait().

4.4.6. Сигнальные (условные) переменные

Мы узнали, как с помощью исключающего семафора защитить переменную от одновременного доступа со стороны двух и более потоков и как посредством обычного семафора реализовать счетчик обращений, доступный нескольким потокам. Сигнальная переменная (называемая также условной переменной) — это третий элемент синхронизации в Linux. Благодаря ему можно задавать более сложные условия выполнения потоков.

Предположим, требуется написать потоковую функцию, которая входит в бесконечный цикл, выполняя на каждой итерации какие-то действия. Но работа цикла должна контролироваться флагом: действие выполняется только в том случае, когда он установлен.

В листинге 4.13 показан вариант такой программы. На каждой итерации цикла потоковая функция проверяет, установлен ли флаг. Поскольку к флагу обращается сразу несколько потоков, он защищается исключающим семафором. Подобная реализация является корректной, но она неэффективна. Если флаг не установлен, потоковая функция будет впустую тратить ресурсы процессора, занимаясь бесцельными проверками флага, а также захватывая и освобождая семафор. На самом деле необходимо как-то перевести функцию в неактивный режим, пока какой-нибудь другой поток не установит этот флаг.

Листинг 4.15. (spin-condvar.c) Простейшая реализация сигнальной переменной

#include


int thread_flag;

pthread_mutex_t thread_flag_mutex;


void initialize_flag() {

 pthread_mutex_init(&thread_flag_mutex, NULL);

 thread_flag = 0;

}


/* Если флаг установлен, многократно вызывается функция do_work().

   В противном случае цикл работает вхолостую. */

void* thread_function(void* thread_arg) {

 while (1) {

  int flag_is_set;

  /* Защищаем флаг с помощью исключающего семафора. */

  pthread_mutex_lock(&thread_flag_mutex);

  flag_is_set = thread_flag;

  pthread_mutex_unlock(&thread_flag_mutex);

  if (flag_is_set)

   do_work();

  /* Если флаг не установлен, ничего не делаем. Просто переходим

     на следующую итерацию цикла. */

 }

 return NULL;

}


/* Задаем значение флага равным FLAG_VALUE. */

void set_thread_flag(int flag_value) {

 /* Защищаем флаг с помощью исключающего семафора. */

 pthread_mutex_lock(&thread_flag_mutex);

 thread_flag = flag_value;

 pthread_mutex_unlock(&thread_flag_mutex);

}

Сигнальная переменная позволяет организовать такую проверку, при которой поток либо выполняется, либо блокируется. Как и в случае семафора, поток может ожидать сигнальную переменную. Поток A, находящийся в режиме ожидания, блокируется до тех пор, пока другой поток. Б, не просигнализирует об изменении состояния этой переменной. Сигнальная переменная не имеет внутреннего счетчика, что отличает ее от семафора. Поток А должен перейти в состояние ожидания до того, как поток Б пошлет сигнал. Если сигнал будет послал раньше, он окажется потерянным и поток А заблокируется, пока какой-нибудь поток не пошлет сигнал еще раз.

Вот как можно сделать предыдущую программу более эффективной.

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

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

1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

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

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

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

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

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

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