Ц Програмирање

Како се користе обрађивачи сигнала на језику Ц?

Како се користе обрађивачи сигнала на језику Ц?
У овом чланку ћемо вам показати како се користе руковаоци сигналима у Линуку помоћу језика Ц. Али прво ћемо разговарати о томе шта је сигнал, како ће генерирати неке уобичајене сигнале које можете користити у свом програму, а затим ћемо погледати како програм може руковати различитим сигналима док се програм извршава. Па, кренимо.

Сигнал

Сигнал је догађај који се генерише да би се обавестио поступак или нит да је стигла нека важна ситуација. Када процес или нит прими сигнал, процес или нит ће зауставити своје деловање и предузети неке радње. Сигнал може бити користан за међупроцесну комуникацију.

Стандардни сигнали

Сигнали су дефинисани у заглављу датотеке сигнал.х као макро константа. Назив сигнала је почео са „СИГ“, а затим следи кратак опис сигнала. Дакле, сваки сигнал има јединствену нумеричку вредност. Ваш програм увек треба да користи име сигнала, а не број сигнала. Разлог је тај што се број сигнала може разликовати у зависности од система, али значење имена биће стандардно.

Макро НСИГ је укупан број дефинисаног сигнала. Вредност НСИГ је један већи од укупног броја дефинисаног сигнала (Сви бројеви сигнала се додељују узастопно).

Следе стандардни сигнали:

Име сигнала Опис
СИГХУП Прекини поступак. Сигнал СИГХУП користи се за пријављивање прекида корисничког терминала, могуће зато што се даљинска веза губи или прекида везу.
ЗНАК Прекините поступак. Када корисник упише знак ИНТР (обично Цтрл + Ц), шаље се сигнал СИГИНТ.
СИГКУИТ Затворите поступак. Када корисник упише знак КУИТ (обично Цтрл + \), шаље се сигнал СИГКУИТ.
СИГИЛЛ Незаконито упутство. Када се покуша извршити смеће или привилегована инструкција, генерише се сигнал СИГИЛЛ. Такође, СИГИЛЛ се може генерисати када се стек прелије или када систем има проблема са покретањем обрађивача сигнала.
СИГТРАП Траце трап. Инструкције тачке прекида и друге инструкције за хватање генерисаће сигнал СИГТРАП. Програм за отклањање погрешака користи овај сигнал.
СИГАБРТ Прекид. Сигнал СИГАБРТ се генерише када се позове функција аборт (). Овај сигнал указује на грешку коју сам програм детектује и пријављује позив функције аборт ().
СИГФПЕ Изузетак са помичним зарезом. Када се догоди фатална аритметичка грешка, генерише се СИГФПЕ сигнал.
СИГУСР1 и СИГУСР2 Сигнали СИГУСР1 и СИГУСР2 могу се користити како желите. Корисно је за њих написати обрађивач сигнала у програму који прима сигнал за једноставну међупроцесну комуникацију.

Подразумевана акција сигнала

Сваки сигнал има подразумевану радњу, једну од следећих:

Термин: Процес ће се завршити.
Језгро: Процес ће завршити и произвести думп датотеку језгра.
Игн: Процес ће занемарити сигнал.
Зауставити: Процес ће се зауставити.
Наставак: Процес ће се наставити од заустављања.

Подразумевана радња се може променити помоћу функције руковаоца. Подразумевана радња неког сигнала не може се променити. СИГКИЛЛ и СИГАБРТ подразумевана радња сигнала не може се променити или занемарити.

Руковање сигналима

Ако процес прими сигнал, процес има могућност избора акције за ту врсту сигнала. Процес може занемарити сигнал, може одредити функцију руковаоца или прихватити задану радњу за ту врсту сигнала.

Помоћу сигнала можемо се носити сигнал или сигакција функцију. Овде видимо како је најједноставније сигнал () функција се користи за руковање сигналима.

инт сигнал () (инт сигнум, воид (* фунц) (инт))

Тхе сигнал () позваће фунц функција ако процес прима сигнал сигнум. Тхе сигнал () враћа показивач у функцију фунц ако успе или врати грешку на еррно и -1 у супротном.

Тхе фунц показивач може имати три вредности:

  1. СИГ_ДФЛ: То је показивач на подразумевану функцију система СИГ_ДФЛ (), проглашен у х датотека заглавља. Користи се за подразумеване радње сигнала.
  2. СИГ_ИГН: То је показивач на функцију занемаривања система СИГ_ИГН (),проглашен у х датотека заглавља.
  3. Кориснички дефинисан показивач функције руковаоца: Кориснички дефинисани тип функције руковаоца је воид (*) (инт), значи да је ретурн тип воид и један аргумент типа инт.

Пример основног руковаоца сигналом

#инцлуде
#инцлуде
#инцлуде
воид сиг_хандлер (инт сигнум)
// Тип повратка функције руковаоца треба бити воид
принтф ("\ нУнутарња функција руковаоца \ н");

инт маин ()
сигнал (СИГИНТ, сиг_хандлер); // Регистрирај обрађивач сигнала
фор (инт и = 1 ;; и ++) // Бесконачна петља
принтф ("% д: Унутар главне функције \ н", и);
спавање (1); // Одлагање за 1 секунду

ретурн 0;

На снимку екрана резултата Пример1.ц, можемо видети да се у главној функцији извршава бесконачна петља. Када је корисник откуцао Цтрл + Ц, извршавање главне функције се зауставља и позива се функција руковаоца сигналом. Након завршетка функције руковаоца, извршење главне функције је настављено. Када је корисник откуцао Цтрл + \, процес се прекида.

Пример занемаривања сигнала

#инцлуде
#инцлуде
#инцлуде
инт маин ()
сигнал (СИГИНТ, СИГ_ИГН); // Регистрирај обрађивач сигнала за игнорисање сигнала
фор (инт и = 1 ;; и ++) // Бесконачна петља
принтф ("% д: Унутар главне функције \ н", и);
спавање (1); // Одлагање за 1 секунду

ретурн 0;

Овде је функција руковаоца регистрована за СИГ_ИГН () функција за игнорисање радње сигнала. Дакле, када је корисник откуцао Цтрл + Ц,  ЗНАК сигнал генерише, али се радња занемарује.

Пример поновне регистрације руковаоца сигналом

#инцлуде
#инцлуде
#инцлуде
воид сиг_хандлер (инт сигнум)
принтф ("\ нУнутарња функција руковаоца \ н");
сигнал (СИГИНТ, СИГ_ДФЛ); // Поново региструј обрађивач сигнала за подразумевану радњу

инт маин ()
сигнал (СИГИНТ, сиг_хандлер); // Регистрирај обрађивач сигнала
фор (инт и = 1 ;; и ++) // Бесконачна петља
принтф ("% д: Унутар главне функције \ н", и);
спавање (1); // Одлагање на 1 секунду

ретурн 0;

На снимку екрана резултата Пример3.ц, можемо видети да када је корисник први пут откуцао Цтрл + Ц, позвала се функција обрађивача. У функцији руковаоца, обрађивач сигнала се региструје на СИГ_ДФЛ за подразумевану акцију сигнала. Када је корисник други пут откуцао Цтрл + Ц, поступак се прекида, што је подразумевана радња ЗНАК сигнал.

Слање сигнала:

Процес такође може изричито да шаље сигнале себи или другом процесу. Функција рисе () и килл () може се користити за слање сигнала. Обе функције су декларисане у сигналу.х датотека заглавља.

инт повишица (инт сигнум)

Функција повишења () која се користи за слање сигнала сигнум на процес позивања (сам). Враћа нулу ако је успешна, а нула вредност ако не успе.

инт килл (пид_т пид, инт сигнум)

Функција убијања која се користи за слање сигнала сигнум на процес или процесну групу назначену пид.

Пример руковаоца сигналом СИГУСР1

#инцлуде
#инцлуде
воид сиг_хандлер (инт сигнум)
принтф ("Унутрашња функција руковаоца \ н");

инт маин ()
сигнал (СИГУСР1, сиг_хандлер); // Региструј обрађивач сигнала
принтф ("Унутар главне функције \ н");
подићи (СИГУСР1);
принтф ("Унутар главне функције \ н");
ретурн 0;

Овде процес шаље сигнал СИГУСР1 себи користећи функцију рисе ().

Подигните са програмом примера убистава

#инцлуде
#инцлуде
#инцлуде
воид сиг_хандлер (инт сигнум)
принтф ("Унутрашња функција руковаоца \ н");

инт маин ()
пид_т пид;
сигнал (СИГУСР1, сиг_хандлер); // Регистрирај обрађивач сигнала
принтф ("Унутар главне функције \ н");
пид = гетпид (); // Обрада ИД-а самог себе
убити (пид, СИГУСР1); // Пошаљите СИГУСР1 себи
принтф ("Унутар главне функције \ н");
ретурн 0;

Ево, процес пошаљи СИГУСР1 сигнал себи користећи килл () функцију. гетпид () користи се за добијање ИД-а самог процеса.

У следећем примеру видећемо како родитељ и дете обрађују комуникацију (Интер Процесс Цоммуницатион) помоћу килл () и сигнална функција.

Комуникација родитеља детета са сигналима

#инцлуде
#инцлуде
#инцлуде
#инцлуде
воид сиг_хандлер_парент (инт сигнум)
принтф ("Родитељ: Примио је сигнал одговора од детета \ н");

воид сиг_хандлер_цхилд (инт сигнум)
принтф ("Дијете: Примио сигнал од родитеља \ н");
спавање (1);
килл (гетппид (), СИГУСР1);

инт маин ()
пид_т пид;
иф ((пид = форк ())<0)
принтф ("Форк није успео \ н");
излаз (1);

/ * Дечји процес * /
иначе ако (пид == 0)
сигнал (СИГУСР1, сиг_хандлер_цхилд); // Регистрирај обрађивач сигнала
принтф ("Дете: чека сигнал \ н");
пауза ();

/ * Надређени процес * /
елсе
сигнал (СИГУСР1, сиг_хандлер_парент); // Региструј обрађивач сигнала
спавање (1);
принтф ("Родитељ: слање сигнала детету \ н");
убити (пид, СИГУСР1);
принтф ("Родитељ: чека одговор \ н");
пауза ();

ретурн 0;

Ево, виљушка () функција ствара подређени процес и враћа нулу подређеном процесу и подређени ИД процеса родитељском процесу. Дакле, пид је проверен како би се одлучило за поступак родитеља и детета. У родитељском процесу се мирује 1 секунду, тако да подређени процес може да региструје функцију руковаоца сигналом и сачека сигнал родитеља. Након 1 секунде родитељског процеса пошаљите СИГУСР1 сигнал детету обради и сачекај одговор детета. У подређеном процесу прво се чека сигнал родитеља, а када се сигнал прими, позива се функција руковаоца. Из функције руковаоца, подређени процес шаље други СИГУСР1 сигнал родитељу. Ево гетппид () функција се користи за добијање ИД-а родитељског процеса.

Закључак

Сигнал у Линуку је велика тема. У овом чланку видели смо како се рукује сигналом од самог основног, а такође смо стекли знање како сигнал генерише, како процес може да пошаље сигнал себи и другим процесима, како се сигнал може користити за међупроцесну комуникацију.

Како инсталирати Леагуе Оф Легендс на Убунту 14.04
Ако сте љубитељ Леагуе оф Легендс, ово је прилика да тестирате Леагуе оф Легендс. Имајте на уму да је ЛОЛ подржан на ПлаиОнЛинук ако сте корисник лину...
Инсталирајте најновију ОпенРА Стратеги Гаме на Убунту Линук
ОпенРА је Либре / Фрее Реал Тиме стратешки механизам који ствара ране Вествоод игре попут класичне Цомманд & Цонкуер: Ред Алерт. Дистрибуирани модови ...
Инсталирајте најновији Долпхин Емулатор за Гамецубе & Вии на Линук
Долпхин Емулатор вам омогућава да играте изабране игре Гамецубе и Вии на Линук Персонал Цомпутерс (ПЦ). Долпхин Емулатор је слободно доступан и емула...