Bosh sahifa Wiki Signal Handler

Signal Handler

Signal Handler — processga asynchronous signal yetkazilganda operatsion tizim chaqiradigan foydalanuvchi funksiyasi. Handler dasturga termination, timer, child holati yoki tashqi boshqaruv hodisasiga javob berish imkonini beradi. Unix signal modeli oddiy callbackdan farq qiladi: handler joriy threadning istalgan xavfsiz bo‘lmagan nuqtasida bajarilishi mumkin va odatiy kutubxona funksiyalarining aksariyatini chaqira olmaydi.

O‘rnatish

POSIX tizimida sigaction signal uchun handler, mask va flaglarni belgilaydi. Eski signal() API’si platformalar o‘rtasida tarixiy farqlarga ega. SA_SIGINFO yoqilsa handler signal raqami bilan birga sender, fault address yoki queue value kabi metadata oladi.

Handler signature konfiguratsiyaga mos bo‘lishi kerak. Noto‘g‘ri function pointer yoki qaytish frame’i undefined behaviorga olib keladi. SIGKILL va SIGSTOP uchun handler o‘rnatib bo‘lmaydi.

Async-signal safety

Signal allocator, stdio yoki lock ushlab turilgan paytda kelishi mumkin. Handler malloc, printf yoki oddiy mutexni chaqirsa qayta kirish deadlock yoki heap corruption tug‘diradi. POSIX faqat cheklangan async-signal-safe funksiyalar ro‘yxatini kafolatlaydi.

Amaliy dizaynda handler volatile sig_atomic_t flagni o‘rnatadi yoki self-pipe/eventfd’ga kichik yozuv qiladi. Asosiy event loop uyg‘onib murakkab ishni odatiy context’da bajaradi. Multi-thread dasturda dedicated thread sigwait bilan signalni synchronous qabul qilishi yanada sodda bo‘lishi mumkin.

Mask va nesting

Handler bajarilayotganda ayni signal odatda avtomatik masklanadi. sa_mask qo‘shimcha signallarni vaqtincha bloklaydi. SA_NODEFER reentrant yetkazishga ruxsat bersa stack to‘lishi va bir xil state parallel buzilishi mumkin.

Handler oldingi maskni qaytishda tiklaydi. setjmp/longjmp orqali handlerdan chiqish mask va resource invariantlarini buzishi mumkin; signal-aware variant va qat’iy contract talab etiladi.

Fault signallari

SIGSEGV, SIGBUS yoki SIGILL handleri diagnostika yozishi yoki maxsus runtime recovery’siga xizmat qilishi mumkin. Noto‘g‘ri instruktsiyaga oddiy qaytish signalni yana takrorlaydi. Umumiy application recovery xavfli, chunki memory invariantlari buzilgan bo‘lishi mumkin.

Crash handler oldindan ochilgan descriptorga minimal async-safe yozuv qiladi va odatda processni standart signal bilan tugatadi. To‘liq symbolization alohida crash collector’da bajariladi.

Thread tanlovi

Process-directed signal uni bloklamagan mos threadlardan biriga yetkaziladi. Thread-directed signal konkret threadga boradi. Barcha workerlar signalni bloklab, bitta signal thread qabul qilsa lifecycle nazorati aniqroq bo‘ladi.

Handler thread-local state’ga kirsa signal qaysi threadda kelganini hisobga oladi. Cancellation, fork va exec bilan mask/disposition inheritance qoidalari test qilinadi.

Signal va locklar

Main code handler bilan ulashadigan oddiy global obyektni mutex bilan himoyalasa, signal aynan mutex ushlangan threadda kelishi mumkin. Handler o‘sha mutexni olsa self-deadlock yuz beradi. Lock-free deb atalgan har operation ham signal-safe emas: atomic implementation ayrim platformada ichki library lock ishlatishi mumkin. Faqat standart kafolatlagan sig_atomic_t amali yoki async-safe descriptor yozuvi tanlanadi. Handler flagi memory ordering va compiler optimizatsiyasini hisobga oladigan type bilan e’lon qilinadi.

Child process hodisasi

SIGCHLD handlerida childlarni waitpid(..., WNOHANG) bilan barcha tayyor statuslar tugaguncha yig‘ish mumkin. Bitta signal bir nechta child exitini birlashtirgani uchun faqat bir marta wait qilish zombie qoldiradi. Murakkab job bookkeeping handler ichida bajarilmaydi; PID va status minimal queue orqali event loopga uzatiladi. Fork bilan handler race’i oldini olish uchun signal vaqtincha masklanadi.

Bog‘liq tushunchalar

signal mask, sigaction, async-signal-safe, sigwait, self-pipe, process signal