В данный момент нас интересует только то приложение, в котором дочерний процесс порождается вызовом
spawnl()
. Используемые приложением механизмы и понятия — сигналы UNIX приоритеты, наследование и инверсия приоритетов — будут рассмотрены позже, поэтому при первом чтении их можно опустить. Нам не хотелось перегружать текст дополнительными «пустыми» примерами, лишь иллюстрирующими применение одной функции. Это приложение, созданное «на будущее», позволит нам отследить крайне актуальный для систем реального времени вопрос о наличии (или отсутствии) наследования приоритетов при посылке сигналов (допустимо как одно, так и другое решение, но оно должно быть однозначно единственным для ОС).
Итак, родительское приложение (
#include
#include
#include
#include
#include
#include
// обработчик сигнала
static void handler(int signo, siginfo_t* info, void* context) {
int oldprio = getprio(0);
setprio(0, info->si_value, sival_int);
cout << "SIG = " << signo << " old priority = "
<< oldprio << " new priority = " << getprio(0) << endl;
setprio(0, oldprio);
}
int main(int argc, char* argv[]) {
// установить обработчик сигнала
sigset_t sig;
sigemptyset(&sig);
//определение #define SIGUSR1 16
sigaddset(&sig, SIGUSR1);
sigprocmask(SIG_BLOCK, &sig, NULL);
struct sigaction act;
act.sa_mask = sig;
act.sa_sigaction = handler;
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGUSR1, &act, NULL) < 0)
perror("set signal handler"), exit(EXIT_FAILURE);
// создать новый (дочерний) процесс
const char* prg = "./p1ch", *sdelay = "3";
pid_t pid =
((argc > 1 ) && (atoi(argv[1]) >= sched_get_priority_min(SCHED_RR)) &&
(atoi(argv[1]) <= sched_get_priority_max(SCHED_RR))) ?
spawnl(P_NOWAIT, prg, prg, sdelay, argv[1], NULL) :
spawnl(P_NOWAIT, prg, prg, sdelay, NULL);
if (pid == -1)
perror("spawn child process"), exit(EXIT_FAILURE);
// размаскировать и ожидать сигнала.
sigprocmask(SIG_UNBLOCK, &sig, NULL);
while (true) {
if (sleep(3) != 0) continue;
cout << "parent main loop: priority = " << getprio(0) << endl;
}
}
Дочернее приложение (
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
int val, del = 5;
if ((argc > 1) &&
(sscanf(argv[1], "%i", &val) == 1) && (val > 0)) del = val;
if ((argc > 2) &&
(sscanf(argv[2], "%i", &val) == 1 ) && (val > 0) &&
(val <= sched_get_priority_max(SCHED_RR)))
if (setprio(0, val) == -1) perror("set priority");
// периодически уведомлять родителя SIGUSR1, используя
// его как сигнал реального времени (с очередью):
while(true) {
sleep(del);