Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QNX/UNIX: Анатомия ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ°Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 12

Автор Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ ОлСг Π˜Π²Π°Π½ΠΎΠ²ΠΈΡ‡

Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π²Ρ‹Π·ΠΎΠ²Π°

spawn*()
(использованиС
exec()
Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ) рассмотрим ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ( Ρ„Π°ΠΉΠ»Ρ‹ p1.cc, p1ch.cc), Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ:

β€’Β Π ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс ( p1) ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Π΅Ρ‚ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ ( p1ch) ΠΈ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΎΡ‚ Π½Π΅Π³ΠΎ поступлСния сигнала

SIGUSR1
(сигналы Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΎΠ±ΡΡƒΠΆΠ΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎΠ·ΠΆΠ΅, Π½ΠΎ здСсь ΠΏΠΎΠΏΡƒΡ‚Π½ΠΎ «вскроСм» ΠΎΠ΄Π½Ρƒ ΠΈΠ· ΠΈΡ… особСнностСй).

β€’Β Π”ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс пСриодичСски посылаСт Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŽ сигнал

SIGUSR1
.

β€’Β Π ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ (с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки запуска) для Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ: ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ посылки сигнала (1-ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π·Π°Π΄Π°Π½ Π² нашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ константой) ΠΈ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс (2-ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€, Π² качСствС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ рСтранслируСтся СдинствСнный ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ запуска родитСля).

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

Π’ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ нас интСрСсуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс пороТдаСтся Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ

spawnl()
. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ ΠΈ понятия β€” сигналы UNIX ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Ρ‹, наслСдованиС ΠΈ инвСрсия ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠ² β€” Π±ΡƒΠ΄ΡƒΡ‚ рассмотрСны ΠΏΠΎΠ·ΠΆΠ΅, поэтому ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ. Нам Π½Π΅ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ тСкст Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ «пустыми» ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ, лишь ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, созданноС Β«Π½Π° Π±ΡƒΠ΄ΡƒΡ‰Π΅Π΅Β», ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π½Π°ΠΌ ΠΎΡ‚ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ ΠΊΡ€Π°ΠΉΠ½Π΅ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ для систСм Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ вопрос ΠΎ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ (ΠΈΠ»ΠΈ отсутствии) наслСдования ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠ² ΠΏΡ€ΠΈ посылкС сигналов (допустимо ΠΊΠ°ΠΊ ΠΎΠ΄Π½ΠΎ, Ρ‚Π°ΠΊ ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, Π½ΠΎ ΠΎΠ½ΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ СдинствСнным для ОБ).

Π˜Ρ‚Π°ΠΊ, Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ( Ρ„Π°ΠΉΠ» p1.cc):

Π‘ΠΈΠ³Π½Π°Π»Ρ‹ ΠΈ наслСдованиС ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠ²

#include <stdlib.h>

#include <stdio.h>

#include <iostream.h>

#include <signal.h>

#include <unistd.h>

#include <sched.h>

// ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала

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;

Β }

}

Π”ΠΎΡ‡Π΅Ρ€Π½Π΅Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ( Ρ„Π°ΠΉΠ» p1ch.cc), ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π²Ρ‹ΡˆΠ΅ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс:

#include <stdio.h>

#include <iostream.h>

#include <sched.h>

#include <unistd.h>

#include <signal.h>

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);

Β  union sigval val;

Β  val.sival_int = getprio(0);

Β  // #define SIGUSR1 16

Β  sigqueue(getppid(), SIGUSR1, val);

Β }