Руководство программиста для Linux


Семафоры - часть 7


Возвращаясь к примеру с принтерами, допустим, что потребовалось определить статус всех пяти принтеров: #define MAX_PRINTERS 5 printer_usage() { int x; for(x=0; xsem_perm.mode); /* Изменяем права доступа к семафору */ sscanf(mode, "%0", &semopts.buf->sem_perm.mode); /* Обновляем внутреннюю структуру данных */ semctl(sid, 0, IPC_SET, semopts); printf("Updated...\n"); }

Программа пытается создать локальную копию внутренней структуры данных для множества семафоров, изменить права доступа и сIPC_SETить их обратно в ядро. Однако, первый вызов semctl-а немедленно вернет EFAULT или ошибочный адрес для последнего аргумента (объединения!). Кроме того, если бы мы не следили за ошибками для этого вызова, то заработали бы сбой памяти. Почему?

Вспомним, что команды IPC_SET/IPC_STAT используют элемент buf объединения, который является указателем на тип semid_ds. Указатели - это указатели, и ничего кроме указателей! Элемент buf должен ссылаться на некий корректный участок памяти, чтобы наша функция работала как полагается. Рассмотрим исправленную версию: void changemode(int sid, char *mode) { int rc; struct semid_ds mysemds; /* Получаем текущие значения для внутренней структуры данных */ /* Сначала указываем на нашу локальную копию! */ semopts.buf = &mysemds; /* Попробуем еще разок! */ if((rc = semctl(sid, 0, IPC_STAT, semopts)) == -1) { perror("semctl"); exit(1); } printf("Old permissions were %o\n", semopts.buf->sem_perm.mode); /* Изменяем права доступа к семафору */ sscanf(mode, "%0", &semopts.buf->sem_perm.mode); /* Обновляем внутреннюю структуру данных */ semctl(sid, 0, IPC_SET, semopts); printf("Updated...\n"); }

semtool: Интерактивное средство для работы с семафорами

Описание

Поведение semtool()-а зависит от аргументов командной строки, что удобно для вызова из скрипта shell-а. Позволяет делать все, что угодно, от создания и манипулирования до редактирования прав доступа и удаления множества семафоров. Может быть использовано для управления разделяемыми ресурсами через стандартные скрипты shell-а.

Синтаксис командной строки




Начало  Назад  Вперед