Сигнал гэдэг нь програм ажиллаж явцад үүсч болох онцгой нөхцөлийг (exceptional condition) хэлнэ. Тухайлбал тасалдал (interrupt), программын ажиллах явцад гарах алдаа (run-time error), эсвэл гаднаас үүсэлтэй нөхцөлүүд (program termination/break) байж болно. Сигналтай ажиллах 2 функц, мөн сигналуудын төрлийг "signal.h" гэсэн толгой файлд тодорхойлсон байдаг.
Дараахь сигналын төрлүүд тодорхойлогдсон байдаг:
SIGABRT - Abort буюу програмын хэвийн бус тасралт (abnormal termination). Жишээ нь abort() функцээр үүснэ.
SIGFPE - Floating point exception буюу алдаатай арифметик үйлдлүүд. Жишээ нь тэгд хуваах, эсвэл дүүрэлт г.м.
SIGILL - Illegal instruction буюу програм зөвшөөрөгдөөгүй/танигдахгүй инструкц (процессорын код) агуулсныг мэдээллэнэ.
SIGINT - Interrupt буюу програмын ажиллагааг зогсоох хүсэлтийн гараас буюу терминалаас тавьсныг мэдээллэнэ.
SIGSEGV - Segment violation буюу хадгалах төхөөрөмж (storage) руу хандсан хандалт буруу хийгдсэнийг мэдээллэнэ. Жишээ нь санах ойн хязгаараас давсан хандалт хийх.
SIGTERM - Terminate буюу програмыг зогсоох хүсэлт хийгдсэнийг мэдээллэнэ.
Дээрх стандарт сигналуудаас гадна өөр сигналыг нэмж тодорхойлох боломжтой. Тэр тохиолдолд сигналын нэр заавал SIG гэсэн эхлэлтэй байх ёстой.
#include
void (*signal(int sig, void (*handler)(int)))(int)
signal() фунцк нь sig сигналыг хүлээн авсан үед ямар функцыг (handler()) түүний боловсруулагчаар сонгохыг тохируулна. Уг боловсруулагч функцын аргумент нь тухайн сигнал байж болно. signal() функцын 2 дахь аргументэд SIG_DFL, SIG_IGN гэсэн тусгай утгыг бас оноож өгч болно. Эхнийх нь сигналыг системд урьдчилан зааж өгсөн байдлаар боловсруулах бол дараагийнх нь сигналыг боловсруулахгүйгээр орхино.
signal() функцээр сигнал болон түүнийг боловсруулагч функцын оноолт амжилттай хийгдсэн тохиолдолд боловсруулагч функцын (handler()) өмнөх утга буцна, харин оноолт хийгдэж чадаагүй бол SIG_ERR гэсэн утга буцах ба errno-н утга 1 болно.
Ямар нэгэн сигнал мэдээлэгдвэл, эхлээд програмын ажиллагаа зогсоно. Энэ нь signal(sig, SIG_DFL) гэсэн оноолттой адил шинжтэй. Дараа нь хэрэв тухайн сигналд боловсруулагч функц оноогдсон байвал уг функцыг дуудаж ажиллуулна. Боловсруулагч функц ажиллагаагаа хэвийн дуусгасан тохиолдолд програмын ажиллагаа зогссон цэгээсээ үргэлжлэн ажиллана. Хэрэв сигналын төрөл SIGFPE байсан бол програм үргэлжлэн ажиллахгүй, харин тодорхой байдалд орно. Иймээс SIGFPE сигнал боловсруулах функцууд нь ямагт abort, exit, эсвэл longjump гэсэн функцуудыг агуулсан байх хэрэгтэй.
Програм өөрөө сигналыг мэдээллэх шаардлага заримдаа гардаг. Энэ тохиолдолд raise() функцыг хэрэглэнэ.
#include
int raise (int sig);
Хэрэв raise() функц амжилттай биелэгдвэл 0 утга, үгүй бол тэгээс ялгаатай утга буцаана.
Дараахь жишээ програмд interrupt сигнал хүлээн авсан тохиолдолд програмын ажиллагааг хэрхэн зогсоож байгааг харууллаа.
#include < stdio.h>
#include < stdlib.h>
#include < signal.h>
FILE *temp_file;
void leave(int sig);
main() {
/* сигнал, түүнийг боловсруулагч функцын оноолтыг хийх */
(void) signal(SIGINT,leave);
/* tmp файлыг бичихээр нээх */
temp_file = fopen("tmp","w");
for(;;) {
/* ямар нэг үйлдэл хийх */
printf("Ready...\n");
/* гараас унших */
(void)getchar();
}
/* програм энд хэзээ ч хүрэхгүй ... */
exit(EXIT_SUCCESS);
}
/*
* SIGINT сигналыг хүлээн авмагц, tmp файлыг хаана
* гэхдээ стандарт функцыг (fprintf, fclose) сигнал боловсруулагчаас
* дуудах нь бүх тохиолдолд ажиллах баталгаагүй, энэ нь тухайн системээс
* хамаарна. Тиймээс энэ код ажиллахгүй бол гайхах хэрэггүй.
*/
void
leave(int sig) {
fprintf(temp_file,"\nInterrupted..\n");
fclose(temp_file);
exit(sig);
}
No comments:
Post a Comment