Основы программирования в Linux - Мэтью Нейл
- Дата:08.09.2024
- Категория: Компьютеры и Интернет / Интернет
- Название: Основы программирования в Linux
- Автор: Мэтью Нейл
- Просмотров:0
- Комментариев:0
Шрифт:
Интервал:
Закладка:
<b>}</b>
В большинстве версий ОС Linux определение объединения semun включено в заголовочный файл (обычно sem.h), несмотря на то, что стандарт X/Open настаивает на том, что вы должны привести собственное объявление. Если вы поймете, что должны объявить его самостоятельно, проверьте, нет ли объявления этого объединения на страницах интерактивного справочного руководства, относящихся к функции semctl. Если вы найдете его, мы полагаем, что вы примените определение из вашего справочного руководства, даже если оно отличается от приведенного на страницах этой книги.
Существует множество разных значений параметра command, допустимых в функции semctl. Обычно применяются два из них, которые описаны далее. Более подробную информацию о функции semctl см. в интерактивном справочном руководстве.
Два часто используемых значения command таковы:
□ SETVAL — применяется для инициализации семафора с заданным значением. Это значение передается как элемент val объединения semun. Такое действие необходимо для того, чтобы увеличить значение семафора перед первым его применением;
□ IPC_RMID — применяется для удаления идентификатора семафора, когда он больше не нужен.
Функция semctl возвращает разные значения, зависящие от параметра command. Если значение команды — IPC_RMID, функция в случае успешного завершения вернет 0 и -1 в противном случае.
Применение семафоров
Как видно из содержания предыдущих разделов, операции с семафорами могут быть очень сложными. Это не самое печальное, потому что программирование многих процессов или потоков с критическими секциями — очень трудная задача сама по себе, и наличие сложного программного интерфейса лишь увеличивает интеллектуальную нагрузку.
К счастью, большинство задач, нуждающихся в семафорах, можно решить, применяя единственный бинарный семафор — простейший тип семафора. В следующем примере (упражнение 14.1) вы используете полный программный интерфейс для создания очень простого интерфейса типа Р и V для бинарного семафора. Затем вы примените этот простенький интерфейс для демонстрации того, как функционируют семафоры.
В экспериментах с семафорами будет использоваться единственная программа sem1.с, которую вы сможете запускать несколько раз. Необязательный параметр будет применяться для того, чтобы показать, отвечает ли программа за создание и уничтожение семафора.
Вывод двух разных символов будет обозначать вход в критическую секцию и выход из нее. Программа, запущенная с параметром, выводит X при входе в критическую секцию и выходе из нее. Другие экземпляры запущенной программы будут выводить символ О при входе в свои критические секции и выходе из них. Поскольку в любой заданный момент времени только один процесс способен войти в свою критическую секцию, все символы X и O должны появляться парами.
Упражнение 14.1. Семафоры1. После системных директив #include вы включаете файл semun.h. Он определяет объединение типа semun в соответствии со стандартом X/Open, если оно уже не описано в системном файле sys/sem.h. Далее следуют прототипы функций и глобальная переменная, расположенные перед входом в функцию main. В ней создается семафор с помощью вызова semget, который возвращает ID семафора. Если программа вызывается первый раз (т.е. вызывается с параметром и argc > 1), выполняется вызов set_semvalue для инициализации семафора и переменной op_char присваивается значение O.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/sem.h>
#include "semun.h"
static int set_semvalue(void);
static void del_semvalue(void);
static int semaphore_p(void);
static int semaphore_v(void);
static int sem_id;
int main(int argc, char *argv[]) {
int i;
int pause_time;
char op_char = 'О';
srand((unsigned int)getpid());
sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);
if (argc >1) {
if (!set_semvalue()) {
fprintf(stderr, "Failed to initialize semaphoren");
exit(EXIT_FAILURE);
}
op_char = 'X';
sleep(2);
}
2. Далее следует цикл, в котором 10 раз выполняется вход в критическую секцию и выход из нее. Вы сначала выполняете вызов функции semaphore_p, которая заставляет семафор ждать, когда эта программа будет готова войти в критическую секцию.
for (i = 0; i < 10; i++) {
if (!semaphore_p()) exit(EXIT_FAILURE);
printf("%c", op_char);
fflush(stdout);
pause_time = rand() % 3;
sleep(pause_time);
printf("%c", op_char);
fflush(stdout);
3. После критической секции вы вызываете функцию semaphore_v, которая освобождает семафор перед повторным проходом цикла for после ожидания в течение случайного промежутка времени. После цикла выполняется вызов функции del_semvalue для очистки кода.
if (!semaphore_v()) exit(EXIT_FAILURE);
pause_time = rand() % 2;
sleep(pause_time);
}
printf("n%d - finishedn", getpid());
- Вопросы истории: UNIX, Linux, BSD и другие - Федорчук Алексей Викторович "alv" - Прочая околокомпьтерная литература
- Linux Mint и его Cinnamon. Очерки применителя - Алексей Федорчук - Программное обеспечение
- Язык программирования C++. Пятое издание - Стенли Липпман - Программирование
- Аквариум. (Новое издание, исправленное и переработанное) - Виктор Суворов (Резун) - Шпионский детектив
- Интерфейс: новые направления в проектировании компьютерных систем - Джефф Раскин - Техническая литература