Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

#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 semaphore\n");

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 - finished\n", getpid);

 if (argc > 1) {

sleep(10);

del_semvalue;

 }

 exit(EXIT_SUCCESS);

}

4. Функция

set_semvalue
инициализирует семафор с помощью команды
SETVAL
в вызове
semctl
. Это следует сделать перед использованием семафора.

static int set_semvalue(void) {

 union semun sem_union;

 sem_union.val = 1;

 if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0);

 return(1);

}

5. У

функции
del_semvalue
почти та же форма за исключением того, что в вызове
semctl
применяется команда
IPC_RMID
для удаления ID семафора.

static void del_semvalue(void) {

 union semun sem_union;

 if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)

fprintf(stderr, "Failed to delete semaphore\n");

}

6. Функция semaphore_p изменяет счетчик семафора на -1. Это операция ожидания или приостановки процесса.

static int semaphore_p(void) {

 struct sembuf sem_b;

 sem_b.sem_num = 0;

 sem_b.sem_op = -1; /* P */

 sem_b.sem_flg = SEM_UNDO;

 if (semop(sem_id, &sem_b, 1) == -1) {

fprintf(stderr, "semaphore_p failed\n");

return(0);

 }

 return(1);

}

7. Функция

semaphore_v
аналогична за исключением задания элемента
sem_op
структуры
sembuf
, равного 1. Это операция "освобождения", в результате которой семафор снова становится доступен.

static int semaphore_v(void) {

 struct sembuf sem_b;

 sem_b.sem_num = 0;

 sem_b.sem_op = 1; /* V */

 sem_b.sem_flg = SEM_UNDO;

 if (semop(sem_id, &sem_b, 1) == -1) {

fprintf(stderr, "semaphore_v failed\n");

return(0);

 }

 return(1);

}

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

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

Далее приведен примерный вывод для двух запущенных экземпляров программы:

$ cc sem1.с -о sem1

$ ./sem1 1 &

[1] 1082

$ ./sem1

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

Мастер порталов

Лисина Александра
8. Гибрид
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер порталов

Газлайтер. Том 21

Володин Григорий Григорьевич
21. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 21

Я не царь. Книга XXIV

Дрейк Сириус
24. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не царь. Книга XXIV

Наследник

Назимов Константин Геннадьевич
3. Травник
Фантастика:
фэнтези
6.80
рейтинг книги
Наследник

Кодекс Охотника. Книга XVIII

Винокуров Юрий
18. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVIII

Барон запрещает правила

Ренгач Евгений
9. Закон сильного
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Барон запрещает правила

Искатель 6

Шиленко Сергей
6. Валинор
Фантастика:
рпг
фэнтези
попаданцы
гаремник
5.00
рейтинг книги
Искатель 6

Мечников. Луч надежды

Алмазов Игорь
8. Жизнь Лекаря с нуля
Фантастика:
альтернативная история
аниме
фэнтези
5.00
рейтинг книги
Мечников. Луч надежды

Родословная. Том 2

Ткачев Андрей Юрьевич
2. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Родословная. Том 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Мастер 9

Чащин Валерий
9. Мастер
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер 9

Воронцов. Перезагрузка. Книга 5

Тарасов Ник
5. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
6.00
рейтинг книги
Воронцов. Перезагрузка. Книга 5

За Горизонтом

Вайс Александр
8. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
За Горизонтом

Петля, Кадетский Корпус. Книга четвертая

Алексеев Евгений Артемович
4. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский Корпус. Книга четвертая