ushort *array; /* используется командами GETALL и SETALL */
};
Это объединение отсутствует в системных заголовочных файлах и должно декларироваться приложением (мы определяем его в заголовочном файле unpipc.h, листинг B.1). Оно передается по значению, а не по ссылке, то есть аргументом является собственно значение объединения, а не указатель на него.
ПРИМЕЧАНИЕ
К сожалению, в некоторых системах (FreeBSD и Linux) это объединение определено в заголовочном файле
Ниже приведен список поддерживаемых значений аргумента cmd. В случае успешного завершения функция возвращает 0, а в случае ошибки – –1, если в описании команды не сказано что-либо другое.
■ GETVAL — возвращает текущее значение semval. Поскольку значение семафора отрицательным быть не может (semval объявляется как unsigned short — беззнаковое короткое целое), в случае успешного возврата значение всегда будет неотрицательным.
■ SETVAL — установка значения semval равным arg.val. В случае успешного выполнения корректировочное значение этого семафора (semadj) устанавливается равным нулю для всех процессов.
■ GETPID — функция возвращает текущее значение поля sempid.
■ GETNCNT — функция возвращает текущее значение поля semncnt.
■ GETZCNT — функция возвращает текущее значение поля semzcnt.
■ GETALL — возвращаются значения semval для всех элементов набора. Значения возвращаются через указатель arg.array, а сама функция при этом возвращает 0. Обратите внимание, что вызывающий процесс должен самостоятельно выделить массив беззнаковых коротких целых достаточного объема для хранения всех значений семафоров набора, а затем сделать так, чтобы arg.array указывал на этот массив.
■ SETALL — установка значений semval для всех элементов набора. Значения задаются через указатель arg.array.
■ IPC_RMID — удаление набора семафоров, задаваемого через идентификатор semid.
■ IPC_SET — установка трех полей структуры semid_ds равными соответствующим полям структуры arg.buf: sem_perm.uid, sem_perm.gid и sem_perm.mode. Поле sem_ctime структуры semid_ds устанавливается равным текущему времени.
■ IPC_STAT — возвращение вызвавшему процессу через аргумент arg.buf текущего значения полей структуры semid_ds для данного набора семафоров. Обратите внимание, что вызывающий процесс должен сначала выделить место под структуру semid_ds и установить на нее указатель arg.buf.
11.5. Простые программы
Поскольку семафоры System V обладают живучестью ядра, мы можем продемонстрировать работу с ними, написав несколько небольших программ, которые будут выполнять с семафорами различные действия. В промежутках между выполнением отдельных программ значения семафоров будут храниться в ядре.
Программа semcreate
Первая программа, текст которой приведен в листинге 11.1,[1] просто создает набор семафоров System V. Параметр командной строки –е соответствует флагу IPC_EXCL при вызове semget, а последним аргументом командной строки является количество семафоров в создаваемом наборе.
//svsem/semcreate.с
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int с, oflag, semid, nsems;
6 oflag = SVSEM_MODE | IPC_CREAT;
7 while ((c = Getopt(argc, argv, "e")) != –1) {
8 switch (c) {
9 case 'e':
10 oflag |= IPC_EXCL;
11 break;
12 }
13 }
14 if (optind != argc – 2)
15 err_quit("usage: semcreate [ –e ]
16 nsems = atoi(argv[optind + 1]);
17 semid = Semget(Ftok(argv[optind], 0), nsems, oflag);
18 exit(0);
19 }
Программа semrmid
Следующая программа, текст которой приведен в листинге 11.2, удаляет набор семафоров из системы. Для этого используется вызов semctl с командой (аргументом cmd) IPC_RMID.
//svsem/semrmid.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int semid;
6 if (argc != 2)