198
берілетін пердеде көрсетілген сигналдарды қосады. Қосылған
сигналдар процеспен еленбейді;
■
SIG_UNBLOCK —
new_mask параметрі ретінде берілген пердеде
көрсетілген сигналдарды процесс пердесінен сигналдарды өшіреді.
Өшірілген сигналдар процеспен еленбейді.
Сигналды перденің мәндері өзгерген болса, оның көне мәнін сақтап
қалу қажет, әйтпесе, мәндері сақталған айнымалылар сілтеме бойынша
old_mask параметрі ретінде жіберіледі.
Егер көне мәнді сақтау
қажеттілігі болмаса, бұл параметрдің мәні ретінде NULL жіберіледі.
Айнымалы процесінде сигналды перденің мәнін сақтау талап етілсе,
old_mask тәрізді жіберілімдер, оны өзгертпей, new_ mask параметрінің
мәні ретінде NULL жіберіледі.
Процестің пердесін анықтайтын, айнымалы sigset_t типін
қалыптастыру үшін үш функция қызмет етеді— sigemptyset(),
sigaddset() и sigdelset().
#include
int sigemptyset( sigset_t *sigmask ) ;
int sigaddset( sigset_t *sigmask, const int
signal_num );
int sigdelset( sigset_t *sigmask, const int signal_num
);
Sigemptyset() функциясы sigmask параметрі секілді берілетін
айнымалыда құлыпталған сигналдардың барлығын тазартады.
Sigaddset() функциясы, signal_num нөмірлі сигналын перденің
блокталған сигналдары тізіміне қосады, мұнда берілген sigmask
параметрі ретінде айнымалы болады. Sigdelset() функциясы кері
әрекетті орындайды — signal_num нөмірлі сигналын sigmask
пердесінде блокталған сигналдарды тізімнен өшіреді. Сәтті орындалу
жағдайында, бұл функциялар 0 қайтарылады, сәтсіз болған жағдайда
(мысалы, sigmask нұсқауында қате болғаны кезінде немесе signal_num
нөмірі қате болған жағдайда) -1 қайтарылады.
Сигналды перделердің қолданысын келесі мысалда қарастырамыз.
Процесс SIGINT сигналын күтеді, оны қабылдағанда бұл типтің жаңа
сигналдарын өңдейді, «Таймер қосылды» хабарламасын шығарады, 5 с
күтеді, «Таймер тоқтатылды» хабарламасы шығады, SIGINT
сигналының өңделуін қалпына келтіреді, оның өңделуін блоктан
шығарады және тағыда сигнал келуін күтеді. Егер SIGINT сигналы 5
секундтық үзілісте келсе, ол еленбей қалады. Қабылданған сигналдың
199
үзілісі, осы жағдайда өңдеуші шақыруының
қайталануынан немесе
әдеттегідей өңдеушінің шақыруға мүмкіндік береді:
#include
#include
sigset_t sigmask;
void handler(int sig_no)
{
sigemptyset(&sigmask ) ;
sigaddset(&sigmask, sig_no ) ;
sigprocmask(SIG_BLOCK, &sigmask, NULL);
printf("Timer started\n");
sleep(5);
printf("Timer stopped\n");
signal( sig_no, &handler ) ;
sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
}
int main()
{
signal( SIGINT, &handler ) ; while (1)
{
pause();
}
}
Келесі міндеттерден бағдарламаларды (оны орындайтын файлдың
атауы— signal5) іске асыру:
#!/bin/bash
./signal5 &
pid=$!
for i in 1 2 3 4 5 6 ; do
sleep 1
kill -SIGINT $pid
done
kill -SIGTERM $pid
экранға шығарылады:
Timer started
Timer stopped
Timer
200
started
./signal5.sh: line 11: 1276 Terminated
Sigemptyset() және sigaddset() функцияларының орындалу уақыты,
өңдеудің басында өте аз. Дегенмен, егер де бұл функцияларды орындау
кезінде сигналдар түсуі мүмккін болса,
онда бұл функциялардың
шақырылуын main() функциясының басына орнын ауыстыруға және
sigaddset(&sigmask, SIGINT) шақыру көмегімен, SIGINT сигналын
блоктаушы перденің қажетті мәнін қалыптастыруға болады. Сигнал
нөмірі өңдеуші параметр арқылы емес, нақты берілетін болғандықтан,
өзінің әмбебаптылығын құрбан етуі мүмкін.
10.3-сурет. Орнатылған сигналды перде
кезінде процестің орындалуы
Егер процесс орындалуы жүрісін уақыт сызығында бейнелесек,
10.3- суретте көрсетілген бейнені алуға болады (екінші сигнал SIGINT
еленбейді).
Достарыңызбен бөлісу: