Использование семафора
Использование семафора
Как уже говорилось выше, семафор является крайне гибким и эффективным средством синхронизации, особенно удобным для построения собственных средств планирования выполнения потоков. В этом смысле семафор представляет ценность не только как самостоятельное средство синхронизации выполнения потоков, но и как материал для построения специфических средств планирования и синхронизации для конкретных задач. Мы уже говорили, что семафор образует самодостаточный базис, позволяющий строить гораздо более сложные средства синхронизации без привлечения других средств синхронизации. В принципе это так, но нет ничего плохого и в смешанном использовании как семафоров, так и мьютексов для построения собственных средств синхронизации.
Проиллюстрируем все вышесказанное на двух примерах. Сначала мы построим «очередь сообщений», предназначенную для трансляции сообщений графической системы к «медленному» обработчику реакций. Это одно из решений весьма распространенной задачи о предотвращении «зависания» пользовательского интерфейса на период выполнения медленного обработчика. Для решения этой задачи обработчик события оконной системы (например, нажатия кнопки или выбора пункта меню) и функция, которая непосредственно производит требуемые действия (предусмотренные по наступлению указанного события - нажатия кнопки), должны располагаться в разных потоках.
Было бы удобно, если бы при поступлении новых данных от графической системы поток обработки автоматически (неявно) разблокировался и немедленно приступал к обработке, а в периоды отсутствия таких данных - простаивал в блокированном состоянии. Для реализации такой схемы мы построили синхронизирующую очередь сообщений, которая использует семафор для уведомления потока обработки о наличии новых данных. В принципе указанная задача сводится к уже упоминавшемуся ранее классу задач о синхронизации производителя и потребителя данных.
class event {
/* класс синхронизирующего события, доставляющего
уведомление о добавлении нового элемента в буфер */
public:
event() { sem_init(&_block, 0, 0); }
~event() { sem_destroy(&_block); }
void wait() { sem_wait(&_block); }
void reset() { sem_post(&_block); }
private:
sem_t _block;
};
/* шаблонный класс очереди данных */
template <class T> class CDataQueue {
public:
CDataQueue() {}
~CDataQueue() {}
void push(T _new_data) {
_data_queue.push(_new_data);
data_event.reset();
}
T pop() {
data_event.wait();
T res = _data_queue.front();
_data_queue.pop();
return res;
}
private:
std::queue<T> _data_queue;
event data_event;
};
Принцип работы CDataQueue заключается в том, что для хранения вновь поступающих данных используется очередь, что делает практически независимыми потоки производителя и потребителя. Независимыми во всех случаях, кроме пустой очереди. Потребитель должен быть блокирован до тех пор, пока нет данных от производителя. Как только производитель внесет данные в очередь, поток потребителя разблокируется и считает эти данные. Тонкость заключается в том, что поток потребителя блокируется сам при вызове функции pop(), а разблокируется из потока производителя при вызове им функции push().
Как видите, в построении специфических средств синхронизации нет ничего сложного, вопреки часто встречающемуся утверждению, что создание средств синхронизации со специфическим поведением неадекватно трудоемко, а простейший код позволяет адаптировать возможности тривиального семафора под конкретную задачу.
А теперь хотелось бы обратить ваше внимание на тот факт, что «безопасным» использованием описанной схемы будет только вариант двух потоков — одного производителя и одного потребителя. Если несколько (более двух) потоков одновременно попробуют выполнить функции pop() или push(), начнется путаница, и чем это закончится, сказать трудно. По своей логике код обеих функций в многопоточной системе требует эксклюзивного исполнения. Чтобы обеспечить исключительный доступ к этим участкам кода, мы могли бы использовать дополнительный семафор, но есть другой вариант — специальное средство синхронизации, разработанное именно для решения задачи взаимного исключения, - мьютекс.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Дросселирование семафора для уменьшения состязательности между потоками
Дросселирование семафора для уменьшения состязательности между потоками Слишком большое количество потоков, соревнующихся между собой за право владения единственным ресурсом, например, мьютексом или объектом CS, могут стать причиной снижения производительности как в
Создание семафора
Создание семафора QNX поддерживает два типа семафоров — неименованные и именованные. Разница между ними заключается в том, что к именованному семафору можно обратиться из любого процесса в системе (или даже по сети QNET с другого сетевого хоста), поскольку такой семафор
Получение статуса семафора
Получение статуса семафора int sem_getvalue(sem_t* sem, int* value);Эта функция используется преимущественно для отладки операций над семафорами. По адресу, указанному в value, устанавливается текущее значение счетчика семафора. Поскольку значение счетчика семафора может измениться в
14.7.1. Использование ftw()
14.7.1. Использование ftw() #include <ftw.h>int ftw(const char *dir, ftwFunctionPointer callback, int depth);Функция ftw() начинает с каталога dir и вызывает указанную в callback функцию для каждого файла в этом каталоге и его подкаталогах. Функция вызывается для всех типов файлов, включая символические ссылки и
Использование tar
Использование tar Утилита tar — одна из самых популярных программ, используемых для резервного копирования в системах Linux и UNIX. Она объединяет несколько файлов в один файл архива, что упрощает передачу информации по сети и сохранение ее на резервном носителе. Название
Использование ip
Использование ip Программа ip предназначена для управления таблицами маршрутизации, в частности, правилами, определенными в них. Выполнение данной программы зависит от значений некоторых подопций опции IP: Advanced Router. Программа ip вызывается следующим образом:ip команда [list |
26.6.3. Контроль семафора
26.6.3. Контроль семафора Для контроля семафора используется системный вызов semctl():int semctl(int semid, int semnum, int cmd, union semun arg);Первый аргумент — это идентификатор семафора, второй — номер семафора во множестве семафоров (нумерация начиняется с 0). В отличие от очереди сообщений, где
Использование
Использование Метапрограммирование и метафункции Прежде чем перейти к изложению дальнейшего материала, полезно ввести понятия метапрограммирования и метафункции. Если внимательнее посмотреть на то, что происходит, когда компилятор встречает пример, подобный
Инициализация значения семафора
Инициализация значения семафора В комментариях к исходному коду в издании этой книги 1990 года неправильно утверждалось, что значения семафоров набора инициализируются нулем при вызове semget с созданием нового семафора. Хотя в некоторых системах это действительно
Использование
Использование Так как MSXML уже давно превратился в стандартный компонент Windows, использовать его можно разными способами - например, в собственных приложениях или как ISAPI-расширение. При разработке XSLT-преобразований MSXML, как правило, применяется либо совместно с браузером
Использование
Использование Легкий вариант, Instant Saxon представляет собой утилиту командной строки saxon.exe, с помощью которой можно применять преобразования к XML-документам:saxon.exe -о result.xml source.xml stylesheet.xslПолная версия Saxon (включающая также исходный код) тоже может использоваться как утилита
Использование
Использование Главной областью применения Oracle XSLT Processor является его использование совместно с технологиями XSQL и XSU для обеспечения Web-доступа к реляционным данным. Кроме этого, Oracle XSLT Processor легко интегрируется в другие приложения и также может выполняться из командной
Использование
Использование Как и любой другой XSLT-процессор, написанный на Java, xt можно без труда использовать в Java-проектах. Помимо этого, xt можно использовать в качестве сервлета и из командной строки.Сервлет-версия xt реализована в классе com.jclark.xsl.sax.XSLservlet и может выполняться на
Использование
Использование Прежде всего, как C-библиотеку, libxslt можно подключать к собственным модулям посредством документированного API, а также при помощи разработанных врапперов использовать в Perl и Python-программах. Поскольку по степени совместимости и разработанности libxslt явно
29.4.3. Использование SSI
29.4.3. Использование SSI Использование сценариев cgi, открывающих Web–страницы с целью отображения небольшого количества сведений, не всегда является оправданным. Например, была отображена дата, но также был создан сценарий cgi, который тоже отображает дату. Не лучше ли было бы