Читаем Linux программирование в примерах полностью

  act.sa_flags |= SA_RESTART; /* Разрешить повторный запуск */

 ret = sigaction(sig, &act, NULL);

  /* Поместить новые установки на место */

 return ret; /* Вернуть результат */

}

В случае успеха возвращаемое значение равно 0 и -1 при ошибке.

10.6.7. Передача сигналов: kill() и killpg()

Традиционная функция Unix для передачи сигналов называется kill(). Имя несколько неправильное; все, что она делает — отправляет сигнал. (Результатом этого часто является завершение получателя сигнала, но это не обязательно верно. Однако, теперь слишком поздно менять имя.) Функция killpg() посылает сигнал определенной группе процессов. Объявления следующие:

#include /* POSIX */

#include


int kill(pid_t pid, int sig);

int killpg(int pgrp, int sig); /* XSI */

Аргумент sig является либо именем сигнала, либо 0. В последнем случае сигнал не посылается, но ядро все равно осуществляет проверку ошибок. В частности, это правильный способ проверки существования данного процесса или группы, а также проверки того, что у вас есть разрешение на передачу сигналов процессу или группе процессов kill() возвращает 0 в случае успеха и -1 при ошибке; errno указывает на проблему.

Правила для значения pid несколько запутаны:

pid > 0   pid является номером процесса, и сигнал посылается этому процессу

pid = 0   Сигнал посылается каждому процессу в группе посылающего процесса.

pid = -1  Сигнал посылается каждому процессу в системе, за исключением специальных системных процессов. Применяется проверка прав доступа. На системах GNU/Linux исключается лишь процесс init (PID 1), но у других систем могут быть другие специальные процессы.

pid < -1  Сигнал посылается группе процессов, представленной абсолютным значением pid. Таким образом, вы можете отправить сигнал всей группе процессов, дублируя возможности killpg(). Эта неортогональность обеспечивает историческую совместимость.

Значение pid для kill() сходно со значением для waitpid() (см. раздел 9.1.6.1 «Использование функций POSIX: wait() и waitpid()»).

Стандартная функция С raise() в сущности эквивалентна

int raise(int sig) {

 return kill(getpid(), sig);

}

Комитет по стандартизации С выбрал имя raise(), поскольку С должен работать также в окружениях, не относящихся к Unix, a kill() была сочтена специфичной для Unix функцией. Представилась также возможность дать этой функции более описательное имя.

killpg() посылает сигнал группе процессов. Пока значение pgrp превышает 1, эта функция эквивалентна 'kill(-pgrp, sig)'. Справочная страница GNU/Linux killpg(2) утверждает, что если pgrp равно 0, сигнал посылается группе отправляющего процесса (Это то же самое, что и kill().)

Как вы могли представить, нельзя послать сигнал произвольному процессу (если вы не являетесь суперпользователем, root). Для обычных пользователей действительный или эффективный UID отправляющего процесса должен соответствовать действительному или сохраненному set-user-ID получающего процесса. (Различные UID описаны в разделе 11.1.1 «Действительные и эффективные ID».)

Однако SIGCONT является особым случаем: пока получающий процесс является членом того же сеанса, что и отправляющий, сигнал пройдет. (Сеансы были кратко описаны в разделе 9.2.1 «Обзор управления заданиями».) Это особое правило позволяет управляющей заданиями оболочке продолжать остановленные процессы-потомки, даже если этот остановленный процесс имеет другой ID пользователя.

10.6.8. Наша история до настоящего времени, эпизод II

System V Release 3 API был предназначен для исправления различных проблем, представленных первоначальным API сигналов V7. В частности, важной дополнительной концепцией является понятие о блокировке сигналов.

Однако, этот API оказался недостаточным, поскольку он работал лишь с одним сигналом за раз, оставляя множество широко открытых окон, через которые могли поступать нежелательные сигналы. POSIX API, работая атомарно с множеством сигналов (маской сигналов процесса, программно представленной типом sigset_t), решает эту проблему, закрывая окна.

Первый набор функций, который мы исследовали, манипулирует значениями sigset_t: sigfillset(), sigemptyset(), sigaddset(), sigdelset() и sigismember().

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных