Signal Mask — threadga qaysi bloklanadigan signallar vaqtincha yetkazilmasligini belgilovchi bitlar to‘plami. Signal mask signalni yo‘q qilmaydi; hodisa pending holatda qoladi va maskdan chiqarilganda yetkazilishi mumkin. POSIX’da mask har threadga tegishli, signal disposition esa odatda butun process uchun umumiydir.
Maskni boshqarish
pthread_sigmask multi-thread dasturda, sigprocmask esa an’anaviy process kontekstida maskni block, unblock yoki to‘liq almashtirish uchun ishlatiladi. Eski maskni saqlab, kritik bo‘limdan keyin aynan tiklash kerak. Noto‘g‘ri “hammasini unblock” boshqa qatlam o‘rnatgan himoyani buzadi.
SIGKILL va SIGSTOP masklab bo‘lmaydi. API ularni setga qo‘shishga urinishni e’tiborsiz qoldirishi mumkin; dastur bu signallarni kechiktirishga tayanmasligi kerak.
Pending signallar
Standard signal bloklangan paytda bir necha marta kelishi odatda bitta pending bitga birlashadi. U nechta hodisa sodir bo‘lganini hisoblash mexanizmi emas. Real-time signallar queue qilinadi va qiymat olib yurishi mumkin, lekin queue limiti mavjud.
Maskdan signal chiqarilgach kernel tegishli threadga delivery rejalashtiradi. Yetkazish aynan unblock chaqirig‘i ichida yoki undan keyingi user-mode qaytish nuqtasida yuz berishi mumkin. Shared state handler uchun oldindan tayyor bo‘lishi lozim.
Atomik kutish
“Flagni tekshir, keyin uxla” ketma-ketligida signal tekshiruv bilan sleep orasida kelib, wakeup yo‘qolishi mumkin. sigsuspend maskni atomik almashtirib signal kelguncha kutadi. pselect va ppoll ham I/O kutish bilan vaqtinchalik signal maskini bir operatsiyada bog‘laydi.
Bu API’lar race’siz event loop qurishga xizmat qiladi. Faqat timeout qo‘yish yo‘qolgan wakeupni to‘g‘rilamaydi, u xatoni sekinroq ko‘rsatadi.
Thread modeli
Yangi thread odatda yaratuvchi threadning signal maskini meros oladi. Dastur startida barcha asynchronous signallarni bloklab, keyin workerlarni yaratish va bitta signal threadda sigwait qilish keng tarqalgan modeldir. Shunda handler cheklovlari o‘rniga oddiy synchronous kod ishlaydi.
Process-directed pending signal qaysi unblocked threadga berilishi har doim deterministik emas. Signal orqali konkret workerga command yuborish o‘rniga thread-safe queue va wakeup primitive’i ishlatiladi.
Handler ichidagi mask
sigaction.sa_mask handler vaqtida qo‘shimcha signallarni bloklaydi. Ayni signal default bo‘yicha handler tugaguncha bloklangan. Critical handler state bir nechta signal turidan himoyalanishi kerak bo‘lsa set aniq beriladi.
Mask juda keng bo‘lsa termination yoki timer uzoq kechikadi. Tracing mask o‘zgarishi, pending set va delivery threadini qayd etadi. Fork/exec va library yaratgan threadlarda meros qoidalari alohida sinovdan o‘tkaziladi.
Fork paytidagi holat
Multi-thread process fork qilganda childda faqat chaqirgan thread qoladi va uning signal maski meros bo‘ladi. Boshqa thread signalni qabul qilishi kutilgan bo‘lsa childda u doim bloklangan qolishi mumkin. Child odatda async-signal-safe amallar bilan tezda exec qiladi; atfork handlerlari mask va lock invariantlarini ehtiyotkor tiklaydi. Exec qilinadigan dastur startup’da o‘z kerakli mask siyosatini aniq o‘rnatadi.
Timer signallari
Periodik timer signali uzoq masklansa standard signal birlashishi mumkin, shuning uchun handler chaqiruvlar soni o‘tgan intervallar soniga teng emas. Timer API overrun count berishi yoki monotonic vaqtni qayta o‘qish talab qilinishi mumkin. Deadline hisoblash signal soniga emas, absolut clock qiymatiga tayanadi. Real-time signal queue’si ham cheklangan va consumer ortda qolsa overload siyosati kerak.
Bog‘liq tushunchalar
pending signal, pthread_sigmask, sigsuspend, pselect, real-time signal, signal delivery