Работа със сигнали една част в Linux

В съвременните операционни системи, не е концепцията за IPC (Комуникация между процесите - IPC) - набор от методи за обмен на данни между процеси и / или конци. Един от начините сигнали са обмен. Концепцията за сигнали, подкрепени от повечето операционни системи, но, например, Windows, не разполага с пълната си подкрепа за използване като средство за IPC - в тези операционни системи, сигналите се прилага само в стандартната библиотека на С.







концепция сигнал

Сигнали може в произволен момент (асинхронно), за да се прекъсне процеса, за да се справят с едно събитие. Процесът може да бъде прекъснат от сигнал започнато от друг процес или ядро. Ядрото използва сигнали за уведомяване процеси на различни събития, като завършването на процеса на дете.

Сигналите имат определен жизнен цикъл. Първоначално се генерира сигнал - процесът се изпраща или генерирани от ядрото. Сигналът е след това очаква доставка на процеса на приемник. Смята се, че периодът на изчакване е времевия интервал между създаването на сигнала на сигнала, и действие, което изпраща сигнал. В края на жизнения цикъл на един сигнал е неговото пресичане (рецепция) процес и извършване на действия, свързани с сигнала.

Прости и надеждни сигнали сигнали

Има разделение на сигнала в проста и надеждна.

Те първоначално са били разработени и се използват прости (ненадеждни) сигнали. Според неговия принцип на работа са подобни на каноничната механизъм за обработка на хардуер прекъсва към процесора. Ако процесът е искал по специален начин, за да се справи с сигнал, той указва на ядрото за това, като посочва специална функция - манипулатор сигнал. При предаване на сигнал процес на ядрото, веднага след като възможни причини сигнален процесор, прекъсване на процеса на работа. След приключване на процеса на изпълнение манипулатор продължава до точката, където е била прекъсната.

Вместо да пишете манипулатор функция, просто можете да укажете на ядрото, че сигналът причинява действието, по подразбиране за него, или че сигналът се игнорира банална.

Цялата тази концепция за работа с сигнали изглежда достатъчно добър, докато сигналът идва на процеса в момент, когато той вече е зает с обработката на следващите сигнал. Тук и очевидни проблеми - отново, причинени от манипулатор сигнал може да развали тези споделени ресурси (структури споделя данни и променливи), които използва. Освен това, в случай на присъединяване на голям брой сигнали на процесорите стека може да расте без граница, което може да причини повреда на програмата.

В процеса на решаване на проблема са разработени надеждни сигнали, които са стандартизирани в POSIX и все още се използва днес. По-късно в статията се смята за надеждни сигнали.

Сигнали и системни функции

Сигналът може да дойде на процеса по времето, когато процесът е в рамките на една система повикване, например, очаква въвеждане на данни чете (). В този случай за развитието може да отидете на следния път: приложението не се опитва да прихване сигнала се прекъсва и ядрото (например, SIGTERM сигнализира пристигането) - когато терминалът е в нестандартна конфигурация, която може да попречи на работата на потребителите. Разбира се, възможно е да се прихване сигнала до ясно терминал в манипулатор сигнал, а след това излизат, но това е доста трудно да се напише манипулатор сигнал, който знае какво прави в момента на прекъсване на програмата, за да се реши дали да се направи терминал чиста или не.

Към днешна дата има реализация на сигнали, който е свободен от тези недостатъци. Решението е, че в изходния сигнал трябва само зададете флаг показва, че при подаване на сигнал, а след това трябва да се гарантира връщането на поканата система с код за грешка, прекъсването на сигнала за повикване. На следващо място, програмата трябва да провери сигнал манипулатор набор флаг, и предприема необходимите действия, например, за да изчистите терминала и да излезете.

Модерен сигнал причинява бавното прилагане на система призовава да се върне код за грешка EINTR един, когато те са прекъснати от входящия сигнал. Бързо системни функции трябва да бъдат прекратени преди сигналът да бъде доставен. Бавно система повикване - система повикване, което изисква неопределен период от време, за нейното изпълнение, като се чете (), изчакайте (), пише (). Всички системни функции са зависими от непредсказуеми ресурси, като например действията на едно лице, данни за мрежата и т.н. Те са бавни. Естествено, всички други системни функции - бързо.

Обикновено програмата обработва кода на грешката EINTR и ако не е нищо фатално, рестартира системата повикването. Повечето операционни системи Unix-подобни в момента правят това по подразбиране - просто трябва да се обработи манипулатор на сигнала, а поканата система ще бъде рестартиран автоматично. подразбиране Linux система разговор не се рестартира, но за всеки един от процеса на сигнала да зададете се обозначава дали да рестартирате системата бавни системни повиквания прекъснати от този сигнал.







изпращане на сигнали

Изпращането на сигнали от един процес към друг, обикновено се извършва с помощта на убийство () система повикването. Неговият първи параметър - PID процес на която се изпраща сигнал; Вторият параметър - броя на сигнала. Ако искаме да изпратим SIGTERM сигнал към процеса с PID 6666, а след това ние използваме унищожени система повикване (), както следва:

Вместо положителните PID стойности могат да бъдат прехвърлени на разговор е равно по сила, но отрицателна. След това той ще бъде изпратен на всички процеси на групата с броя равна на модула предава PID. Ако PID е 0, сигналът се изпраща на всички процеси на групата, към която се отнася текущия процес. Тези възможности са основно използваните снаряди за контрол на работата.

Ако PID прехвърляне на смъртността система повикване () -1, сигналът ще бъде изпратен на всички процеси, с изключение на първоначален. Тази възможност се използва за изключване на системата.

По-подробна информация за убийство на системата повикване (), вижте два мъж убие.

Изпрати самия процес на сигнал може да използвате рейза на системата повикване (), която приема един параметър - номера на сигнала. например:

Разбира се, всеки един от разглежданите система кол връща нула за успех и различна от нула, ако е имало някаква грешка.

засичане сигнали

Всички програми подчинен стандарт POSIX регистрират своите товарачи сигнали с помощта на системата sigaction повикване (). Тази система заявка приема три параметъра: първата - вътр Signum - брой заловено сигнал. Второ - структура sigaction * акт - указател към структура, която описва правилата за настройка манипулатор. Третият вариант - структура sigaction * oact - вече приема правилата на манипулатор сигнал. Или вторият или третият (но не и двете!), Параметърът може да бъде настроен да NULL, ако е необходимо.

Struct sigaction структура има следното описание:

sa_handler - указател към сигнализира манипулатор, водачът трябва да бъдат декларирани, както следва:

където един параметър - номер на сигнал, който е в манипулатор. sa_handler също може да бъде равна SIG_IGN - процес сигнал се игнорира и SIG_DFL - сигнал предизвиква действието по подразбиране, като прекъсване на процеса.

sa_mask - набор от сигнали, които трябва да бъдат блокирани от повикване дадена една и съща структура на сигналния процесор. Как да ги инсталирате, се обсъжда по-нататък.

параметър sa_flags позволява метод за промяна на поведението на сигнала. Параметърът може да отнеме само четири стойности, които, обаче, могат да се комбинират с помощта на "ИЛИ" малко работа:

  1. SA_NOCLDSTOP - изпратете SIGCHLD сигнал само в случай на прекъсване на процеса на дете. Спирането на процеса на дете не изпраща сигнал.
  2. SA_NODEFER - емулация прост (ненадеждни) сигнализация.
  3. SA_RESTHAND - след пристигането на сигнала при неговото рестартиране манипулатор SIG_DFL.
  4. SA_RESTART - рестартиране на системата повикване след манипулатор сигнал. Ако сигналът не е зададен, обаждането система връща EINTR грешка.

Както обикновено, ако е успешно, sigaction () връща 0, а в случай на грешки - отрицателна стойност.

обработва сигнали маска

Добавянето на сигнали по структура sigset_t sa_mask, неговото пречистване и т.н. осъществява чрез използване sigemptyset () набор от функции, sigfillset (), sigaddset (), sigdelset (). Първите две функции да вземат един параметър - указател към структура sigset_t. Тези функции са пречистени и запълни всички възможни сигнали sigset_t структура съответно.

Последните две функции са съответно добавят и отстраняват от определена структура сигнал и имат два параметъра. Първият им аргумент - указател към sigset_t структура, а втората - номера на сигнала.

Всички тези функции се върнат 0 при успех и редица не е равна на нула - грешка.

Освен това, има и друга функция, която проверява дали заяви сигнал от серията - sigismember (). Параметрите му са същите като sigaddset () параметри. Функцията връща 1, ако сигналът е в комплекта, 0 - ако не е, и отрицателни числа - ако грешката, което е настъпило.

В допълнение, ние може да създаде списък с аларма, доставката на които процесът ще бъде блокиран. Това се извършва чрез sigprocmask функция (INT как, Конст sigset_t * комплект, sigset_t * oldset).

Неговият първи параметър описва какво трябва да се направи:

  1. SIG_BLOCK - сигнали от набор от съвкупност блокиран;
  2. SIG_UNBLOCK - сигнали от набор от съвкупност отключи;
  3. SIG_SETMASK - сигнали от набор от набор са блокирани, а другите са отключени.

Вторият параметър е указател към същия набор от сигнали, които са заключени / отключена. Ако тя е NULL, тогава стойността на първия параметър се игнорира от поканата система.

Третият параметър - указател към маска сигнал вече е в употреба; тя може да се постави в NULL, ако не са необходими тези данни.

sigpending () функция може да се използва за извличане на списък с чакащи сигнали, което отнема на един параметър - указател към sigset_t структура, която ще бъде написана набор от висящите сигнали.

Принципи за писане сигнални указатели

Един от най-важните правила за писане сигнал манипулатор - водачът трябва да е входящ, т.е. тя трябва да се даде възможност за отзоваване, когато процесът вече е в манипулатор. Трябва да се грижи за този сигнал манипулатор не използва глобална структура на данните или бавни системни функции. Ако се избегне това, уви, не е възможно, е необходимо да се грижи за защитата на манипулатор обаждане по време на структурата на данните или система повикване. Това може да се постигне, като блокира по време на предаване на сигнала, който сега работи манипулатор с помощта sigprocmask системата повикване (). Например, ние имаме манипулатор за SIGCHLD, да го заключите, както следва:

Освен всичко по-горе, като се смята, че водачът трябва да е възможно най-просто - в идеалния случай, той трябва да се постави флаг и края, и всичко останало, трябва да носи по-голямата част от програмата.

заключение

Горното е основният материал за разбиране на сигнали концепция. По принцип, това трябва да е достатъчно, че вече са започнали да използват работата със сигнали, в техните програми.

В края на цикъла ще бъдат разказа как да се получи (и изпращане) допълнителните данни, форма на сигнала, ако ви липсва обичайната информация, че сигналът идва от някъде в процеса.