Читаем Linux API. Исчерпывающее руководство полностью

./t_sigwaitinfo: PID is 3837

./t_sigwaitinfo: signals blocked

./t_sigwaitinfo: about to delay 60 seconds

[1] 3837

$ ./t_sigqueue 3837 43 100 Отправить сигнал 43

./t_sigqueue: PID is 3839, UID is 1000

$ ./t_sigqueue 3837 42 200 Отправить сигнал 42

./t_sigqueue: PID is 3840, UID is 1000

Со временем программа завершает период сна — и цикл с функцией sigwaitinfo() принимает поставленные в очередь сигналы. (На экране приглашения оболочки перемешаны с выводом программы, так как программа t_sigwaitinfo распечатывает вывод из фонового режима). Как и в случае с сигналами реального времени, перехваченными обработчиком, мы видим, что сигналы доставляются в порядке увеличения их номера, а также что структура siginfo_t, передаваемая обработчику сигнала, позволяет нам получить идентификатор процесса и идентификатор пользователя процесса, пославшего сигнал:

$ ./t_sigwaitinfo: finished delay

got signal: 42

si_signo=42, si_code=–1 (SI_QUEUE), si_value=200

si_pid=3840, si_uid=1000

got signal: 43

si_signo=43, si_code=–1 (SI_QUEUE), si_value=100

si_pid=3839, si_uid=1000

Мы продолжаем, используя команду оболочки kill для отправки сигнала в процесс. В этот раз мы увидим, что полю si_code присвоено значение SI_USER (вместо SI_QUEUE):

Нажмите Enter, чтобы увидеть следующее приглашение оболочки

$ echo $$ Отобразить PID оболочки

3744

$ kill — USR1 3837 Оболочка посылает SIGUSR1 с помощью kill()

$ got signal: 10 Доставка SIGUSR1

si_signo=10, si_code=0 (SI_USER), si_value=100

si_pid=3744, si_uid=1000 3744 — это PID оболочки

Нажмите Enter, чтобы увидеть следующее приглашение оболочки

$ kill %1 Завершить программу с помощью SIGTERM

$

Нажмите Enter, чтобы увидеть уведомление о завершении фоновой задачи

[1]+ Done./t_sigwaitinfo 60

В выводе для принятого сигнала SIGUSR1 мы видим, что полю si_value присвоено значение 100. Это то значение, с каким данное поле было инициализировано предшествующим сигналом, отправленным с помощью функции sigqueue(). Ранее отмечалось, что поле si_value содержит валидную информацию только для сигналов, посланных с помощью функции sigqueue().


Листинг 22.6. Синхронное ожидание сигналов с sigwaitinfo()

signals/t_sigwaitinfo.c

#define _GNU_SOURCE

#include

#include

#include

#include "tlpi_hdr.h"


int

main(int argc, char *argv[])

{

int sig;

siginfo_t si;

sigset_t allSigs;


if (argc > 1 && strcmp(argv[1], "-help") == 0)

usageErr("%s [delay-secs]\n", argv[0]);

printf("%s: PID is %ld\n", argv[0], (long) getpid());


/* Блокировать все сигналы (исключая SIGKILL и SIGSTOP) */

sigfillset(&allSigs);

if (sigprocmask(SIG_SETMASK, &allSigs, NULL) == –1)

errExit("sigprocmask");

printf("%s: signals blocked\n", argv[0]);

if (argc > 1) {

/* Пауза для того, чтобы сигналы могли быть отправлены нам */

printf("%s: about to delay %s seconds\n", argv[0], argv[1]);

sleep(getInt(argv[1], GN_GT_0, "delay-secs"));

printf("%s: finished delay\n", argv[0]);

}


for (;;) { /* Получать сигналы до SIGINT (^C) или SIGTERM */

sig = sigwaitinfo(&allSigs, &si);

if (sig == –1)

errExit("sigwaitinfo");

if (sig == SIGINT || sig == SIGTERM)

exit(EXIT_SUCCESS);


printf("got signal: %d (%s)\n", sig, strsignal(sig));

printf(" si_signo=%d, si_code=%d (%s), si_value=%d\n",

si.si_signo, si.si_code,

(si.si_code == SI_USER)? "SI_USER":

(si.si_code == SI_QUEUE)? "SI_QUEUE": "other",

si.si_value.sival_int);

printf(" si_pid=%ld, si_uid=%ld\n",

(long) si.si_pid, (long) si.si_uid);

}

}

signals/t_sigwaitinfo.c

Системный вызов sigtimedwait() — это вариация функции sigwaitinfo(). Единственное отличие заключается в том, что функция sigtimedwait() позволяет ограничить время ожидания.

#define _POSIX_C_SOURCE 199309

#include


int sigtimedwait(const sigset_t *set, siginfo_t *info,

const struct timespec *timeout);

Возвращает номер доставленного сигнала при успешном завершении или –1 при ошибке или тайм-ауте (EAGAIN)

Аргумент timeout устанавливает максимальное количество времени, на протяжении которого функция sigtimedwait() будет ожидать сигнал. Этот аргумент — это указатель на структуру следующего типа:

struct timespec {

time_t tv_sec; /* Секунды ('time_t' целочисленный тип) */

long tv_nsec; /* Наносекунды */

};

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

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

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

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

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