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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма UNIXΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 52

Автор РобачСвский АндрСй ΠœΠΈΡ…Π°ΠΉΠ»ΠΎΠ²ΠΈΡ‡

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΌ интСрфСйсом ΠΊ сигналам UNIX являСтся ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠ°Ρ, Π½ΠΎ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ поддСрТиваСмая Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ систСм функция signal(3C). Π­Ρ‚Π° функция позволяСт ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ сигнала, которая ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ устанавливаСтся ядром UNIX. ΠŸΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ fork(2) процСсс наслСдуСт Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ сигналов ΠΎΡ‚ своСго родитСля. Однако ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ exec(2) диспозиция всСх ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… сигналов Π±ΡƒΠ΄Π΅Ρ‚ установлСна Π½Π° дСйствиС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Π­Ρ‚ΠΎ Π²ΠΏΠΎΠ»Π½Π΅ СстСствСнно, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Ρ€Π°Π· Π½ΠΎΠ²ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π΅ содСрТит Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ диспозициСй сигнала ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ exec(2). Ѐункция signal(3C) ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅:

#include <signal.h>

void(*signal(int sig, void (*disp)(int)))(int);

АргумСнт

sig
опрСдСляСт сигнал, Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ.

АргумСнт

disp
опрСдСляСт Π½ΠΎΠ²ΡƒΡŽ Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ сигнала, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ опрСдСлСнная ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ функция-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΈΠ»ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ:

SIG_DFL
Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ядру, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ процСссом сигнала Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ систСмный ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, Ρ‚.Π΅. Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ дСйствиС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.
SIG_IGN
Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ сигнал слСдуСт ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ. Напомним, Ρ‡Ρ‚ΠΎ Π½Π΅ всС сигналы ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ.

Π’ случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ signal(3C) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΡƒΡŽ Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽΒ β€” это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ функция-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала ΠΈΠ»ΠΈ систСмныС значСния

SIG
_DFL ΠΈΠ»ΠΈ
SIG_IGN
. Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использовано для восстановлСния диспозиции Π² случаС нСобходимости.

ИспользованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ signal(3C) ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ сСмантику ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΡ… ΠΈΠ»ΠΈ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ½Ρ‹Ρ… сигналов. ΠŸΡ€ΠΎΡ†Π΅ΡΡ ΠΏΡ€ΠΈ этом ΠΈΠΌΠ΅Π΅Ρ‚ вСсьма слабыС возмоТности управлСния сигналами. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, процСсс Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сигнал, Ρ‚. Π΅. ΠΎΡ‚Π»ΠΎΠΆΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сигнала Π½Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ выполнСния критичСского участка ΠΊΠΎΠ΄Π°. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сигнала, Π΅Π³ΠΎ диспозиция устанавливаСтся Π½Π° дСйствиС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Данная функция ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ Π΅ΠΉ сСмантика сохранСны для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ старых вСрсий ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π’ связи с этим Π² Π½ΠΎΠ²Ρ‹Ρ… прилоТСниях слСдуСт ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ использования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ signal(3C). Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ для ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅ΠΉ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ использования сигналов, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π½ΠΈΠΆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ этот интСрфСйс:

#include <signal.h>

/* Ѐункция-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала */

static void sig_hndlr(int signo) {

Β /* Восстановим Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ */

Β signal(SIGINT, sig_hndlr);

Β printf("ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ сигнал SIGINT\n");

}

main() {

Β /* Установим Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ */

Β signal(SIGINT, sih_hndlr);

Β signal(SIGUSR1, SIG_DFL);

Β signal(SIGUSR2, SIG_IGN);

Β /* БСсконСчный Ρ†ΠΈΠΊΠ» */

Β while(1)

Β  pause();

}

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π° диспозиция Ρ‚Ρ€Π΅Ρ… сигналов:

SIGINT
,
SIGUSR1
ΠΈ
SIGUSR2
. ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сигнала
SIGINT
вызываСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сигнала
SIGUSR1
производится дСйствиС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (процСсс Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ), Π° сигнал
SIGUSR2
игнорируСтся. ПослС установки диспозиции сигналов процСсс запускаСт бСсконСчный Ρ†ΠΈΠΊΠ», Π² процСссС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ вызываСтся функция pause(2). ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сигнала, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ игнорируСтся, pause(2) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ -1, Π° пСрСмСнная errno устанавливаСтся Ρ€Π°Π²Π½ΠΎΠΉ
EINTR
. Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сигнала
SIGINT
ΠΌΡ‹ Π²Ρ‹Π½ΡƒΠΆΠ΄Π΅Π½Ρ‹ Π²ΠΎΡΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡƒΡŽ Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ сигнала этого Ρ‚ΠΈΠΏΠ° Π²Ρ‹Π·Π²Π°Π»ΠΎ Π±Ρ‹ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ выполнСния процСсса (дСйствиС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ).

ΠŸΡ€ΠΈ запускС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

$ <b>Π°.out &amp;</b>

[1] 8365Β Β Β Β Β Β Β Β Β Β Β Β 
Β PID ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½ΠΎΠ³ΠΎ процСсса

$ <b>kill -SIGINT 8365</b>

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ сигнал SIGINT
Π‘ΠΈΠ³Π½Π°Π» SIGINT ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‡Π΅Π½

$ <b>kill -SIGUSR2 8365 </b>
Β Π‘ΠΈΠ³Π½Π°Π» SIGUSR2 игнорируСтся

$ <b>kill -SIGUSR1 8365 </b>

[1]+ User Signal 1Β Β 
Β Π‘ΠΈΠ³Π½Π°Π» SIGUSR1 Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π·Π°Π²Π΅Ρ€-

a.outΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β 
 шСниС выполнСния процСсса

$

Для отправлСния сигналов процСссу использована ΠΊΠΎΠΌΠ°Π½Π΄Π° kill(1), описанная Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ Π³Π»Π°Π²Π΅.

НадСТныС сигналы

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ POSIX. 1 ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ» Π½ΠΎΠ²Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ управлСния сигналами. основанный Π½Π° интСрфСйсС 4.2BSD UNIX ΠΈ Π»ΠΈΡˆΠ΅Π½Π½Ρ‹ΠΉ рассмотрСнных Π²Ρ‹ΡˆΠ΅ нСдостатков.

МодСль сигналов, прСдлоТСнная POSIX, основана Π½Π° понятии Π½Π°Π±ΠΎΡ€Π° сигналов (signal set), описываСмого ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠ°

sigset_t
. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π±ΠΈΡ‚ этой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° ΠΎΠ΄ΠΈΠ½ сигнал. Π’ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… систСмах Ρ‚ΠΈΠΏ
sigset_t
ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π»ΠΈΠ½Ρƒ 32 Π±ΠΈΡ‚Π°, ограничивая количСство Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… сигналов числом 32.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π½Π°Π±ΠΎΡ€Π°ΠΌΠΈ сигналов:

#include &lt;signal.h&gt;

int sigempyset(sigset_t *set);

int siufillset(sigset_t *set);

int sigaddset(sigset_t *set, int signo);

int sigdelset(sigset_t *set, int signo);

int sigismember(sigset_t *set, int signo);

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ signal(3C), ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‰Π΅ΠΉ Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ сигналов, Π΄Π°Π½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ структуру Π΄Π°Π½Π½Ρ‹Ρ…

sigset_t
, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ процСссом. Для управлСния нСпосрСдствСнно сигналами ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ рассмотрим ΠΏΠΎΠ·ΠΆΠ΅.

Ѐункция sigemptyset(3C) ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π°Π±ΠΎΡ€, очищая всС Π±ΠΈΡ‚Ρ‹. Если процСсс Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ sigfillset(3C), Ρ‚ΠΎ Π½Π°Π±ΠΎΡ€ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ всС сигналы, извСстныС систСмС. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ sigaddset(3C) ΠΈ sigdelset(3C) ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ сигналы Π½Π°Π±ΠΎΡ€Π°. Ѐункция sigismember(3C) позволяСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π»ΠΈ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ

signo
сигнал Π² Π½Π°Π±ΠΎΡ€.

ВмСсто Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ signal(3C) стандарт POSIX. 1 опрСдСляСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sigaction(2), ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΡƒΡŽ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΄ΠΈΡΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ сигналов, ΡƒΠ·Π½Π°Ρ‚ΡŒ Π΅Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ Ρ‚ΠΎ ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ. Ѐункция ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅: