Вход/Регистрация
Программирование для Linux. Профессиональный подход
вернуться

Самьюэл Алекс

Шрифт:

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

В Linux имеются две немного отличающиеся реализации семафоров. Та, которую мы опишем ниже, соответствует стандарту POSIX. Такие семафоры применяются для организации взаимодействия потоков. Другая реализация, служащая целям межпроцессного взаимодействия, рассмотрена в разделе 5.2, "Семафоры для процессов". При работе с семафорами необходимо включить в программу файл

<semaphore.h>
.

Семафор представляется переменной типа

sem_t
. Семафор следует предварительно инициализировать с помощью функции
sem_init
, передав ей указатель на переменную семафора. Второй параметр этой функции должен быть равен нулю, [14] а третий — это начальное значение счетчика семафора.

Чтобы выполнить операцию ожидания семафора, необходимо вызвать функцию

sem_wait
. Функция
sem_post
устанавливает семафор. Есть также функция
sem_trywait
, реализующая операцию неблокирующего ожидания. Она напоминает функцию
pthread_mutex_trylock
: если операция ожидания приведет к блокированию потока из-за того, что счетчик семафора равен нулю, функция немедленно завершается, возвращая код ошибки
EAGAIN
.

14

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

В Linux имеется функция

sem_getvalue
, позволяющая узнать текущее значение счетчика семафора. Это значение помещается в переменную типа
int
, на которую ссылается второй аргумент функции. Не пытайтесь на основании данного значения определять, стоит ли выполнять операцию ожидания или установки, так как это может привести к возникновению гонки: другой поток способен изменить счетчик семафора между вызовами функции
sem_getvalue
и какой-нибудь другой функции работы с семафором. Доверяйте только атомарным функциям
sem_wait
и
sem_post
.

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

Листинг 4.12. (job-queue3.c) Работа с очередью заданий с применением семафора

#include <malloc.h>

#include <pthread.h>

#include <semaphore.h>

struct job {

 /* Ссылка на следующий элемент связанного списка. */

 struct job* next;

 /* Другие поля, описывающие требуемую операцию... */

};

/* Список отложенных заданий. */

struct job* job_queue;

/* Исключающий семафор, защищающий очередь. */

pthread_mutex_t job_queue_mutex =

 PTHREAD_MUTEX_INITIALIZER;

/* Семафор, подсчитывающий число гаданий в очереди. */

sem_t job_queue_count;

/* Начальная инициализация очереди. */

void initialize_job_queue {

 /* Вначале очередь пуста. */

 job_queue = NULL;

 /* Устанавливаем начальное значение счетчика семафора

равным 0. */

 sem_init(&job_queue_count, 0, 0);

}

/* Обработка заданий до тех пор, пока очередь не опустеет. */

void* thread_function(void* arg) {

 while (1) {

struct job* next_job;

/* Дожидаемся готовности семафора. Если его значение больше

нуля, значит, очередь не пуста; уменьшаем счетчик на 1.

В противном случае операция блокируется до тех пор, пока

в очереди не появится новое задание. */

sem_wait(&job_queue_count);

/* Захват исключающего семафора, защищающего очередь. */

pthread_mutex_lock(&job_queue_mutex);

/* Мы уже знаем, что очередь не пуста, поэтому без лишней

проверки запрашиваем новое задание. */

next_job = job_queue;

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

job_queue = job_queue->next;

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

  • Читать дальше
  • 1
  • ...
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: