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

  /* Теперь можно проверить, является ли очередь пустой. */

  if (job_queue == NULL)

   next_job = NULL;

  else {

   /* Запрашиваем следующее задание. */

   next_job = job_queue;

   /* Удаляем задание из списка. */

   job_queue = job_queue->next;

  }


  /* Освобождаем семафор, так как работа с очередью окончена. */

  pthread_mutex_unlock(&job_queue_mutex);

  /* Если очередь пуста, завершаем поток. */

  if (next_job == NULL)

   break;

  /* Выполняем задание. */

  process_job(next_job);

  /* Очистка. */

  free(next_job);

 }

 return NULL;

}

Все операции доступа к совместно используемому указателю job_queue происходят между вызовами функций pthread_mutex_lock() и pthread_mutex_unlock(). Объект задания, ссылка на который хранится в переменной next_job, обрабатывается только после того, как ссылка на него удаляется из очереди, что позволяет обезопасить этот объект от других потоков.

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

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

void enqueue_job(struct job* new_job) {

 pthread_mutex_lock(&job_queue_mutex);

 new_job->next = job_queue;

 job_queue = new_job;

 pthread_mutex_unlock(&job_queue_mutex);

}

4.4.3. Взаимоблокировки исключающих семафоров

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

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

■ Захват быстрого семафора (используется по умолчанию) приведет к взаимоблокировке. Функция, обращающаяся к захваченному семафору данного типа, заблокирует поток до тех пор, пока семафор не будет освобожден. Но семафор принадлежит самому потоку, поэтому блокировка никогда не будет снята.

■ Захват рекурсивного семафора не приведет к взаимоблокировке. Семафор данного типа запоминает, сколько раз функция pthread_mutex_lock() была вызвана в потоке, которому принадлежит семафор. Чтобы освободить семафор и позволить другим потокам обратиться к нему, необходимо аналогичное число раз вызвать функцию pthread_mutex_unlock()

.

■ Операционная система Linux обнаруживает попытку повторно захватить контролирующий семафор и сигнализирует об этом: при очередном вызове функции pthread_mutex_lock() возвращается код ошибки EDEADLK.

По умолчанию в Linux создается быстрый семафор. В двух других случаях требуется предварительно создать объект атрибутов семафора, объявив переменную типа pthread_mutexattr_t и передав указатель на нее функции pthread_mutexattr_init(). Затем нужно задать тип исключающего семафора с помощью функции pthread_mutexattr_setkind_np(). Первым ее аргументом является указатель на объект атрибутов семафора; второй аргумент равен PTHREAD_MUTEX_RECURSIVE_NP в случае рекурсивного семафора и PTHREAD_MUTEX_ERRORCHECK_NP — в случае контролирующего семафора. Указатель на полученный объект атрибутов необходимо передать функции pthread_mutex_init(), которая создаст семафор. После этого нужно удалить объект атрибутов с помощью функции pthread_mutexattr_destroy().

Следующий фрагмент программы иллюстрирует процесс создания контролирующего семафора:

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

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

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

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

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

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

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

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

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