linux调用信号处理程序后返回,如何在Linux上执行异步信号处理程序?
Source#1(Andries Brouwer)對于單線程進程是正確的 . 源#2(SCO Unix)對于Linux是錯誤的,因為Linux不喜歡sigwait中的線程(2) . 關于第一個可用的線程,Moshe Bar是正確的 .
Which thread gets the signal? Linux的手冊頁是一個很好的參考 . 進程使用帶有CLONE_THREAD的clone(2)來創(chuàng)建多個線程 . 這些線程屬于"thread group"并共享一個進程ID . 克隆手冊(2)說,
可以使用kill(2)將信號作為整體(即,TGID)發(fā)送到線程組,或者使用tgkill(2)發(fā)送到特定線程(即,TID) . 信號處理和操作在整個過程中:如果未處理的信號被傳遞給線程,那么它將影響(終止,停止,繼續(xù),被忽略)線程組的所有成員 . 每個線程都有自己的信號掩碼,由sigprocmask(2)設置,但信號可以是掛起的:對于整個進程(即,可傳遞給線程組的任何成員),當與kill(2)一起發(fā)送時;或者與tgkill(2)一起發(fā)送的單個線程 . 對sigpending(2)的調用返回一個信號集,該信號集是整個過程中待處理的信號和為調用線程掛起的信號的并集 . 如果使用kill(2)向線程組發(fā)送信號,并且線程組已經為信號安裝了一個處理程序,那么將在沒有阻塞該線程組的線程組中任意選擇的一個成員中調用該處理程序 . 信號 . 如果組中的多個線程正在等待使用sigwaitinfo(2)接受相同的信號,則內核將任意選擇其中一個線程來接收使用kill(2)發(fā)送的信號 .
Linux不是SCO Unix,因為Linux可能會向任何線程發(fā)出信號,即使是某些線程線程正在等待信號(使用sigwaitinfo,sigtimedwait或sigwait),而某些線程則沒有 . sigwaitinfo(2)的手冊警告說,
在正常使用中,調用程序通過事先調用sigprocmask(2)來阻塞set中的信號(這樣,如果它們在連續(xù)調用sigwaitinfo()或sigtimedwait()之間變?yōu)閽炱?#xff0c;則不會發(fā)生這些信號的默認處置)并且不為這些信號 Build 處理程序 . 在多線程程序中,應該在所有線程中阻塞信號,以防止信號在調用sigwaitinfo()或sigtimedwait()之外的線程中根據(jù)其默認處置進行處理 .
為信號選擇線程的代碼位于linux/kernel/signal.c(鏈接指向GitHub 's mirror). See the functions wants_signal() and completes_signal(). The code picks the first available thread for the signal. An available thread is one that doesn' t阻塞信號并且隊列中沒有其他信號 . 代碼首先檢查主線程,然后檢查其他線程如果沒有線程可用,那么信號會被卡住,直到某個線程解除阻塞信號或清空其隊列 .
What happens when a thread gets the signal? 如果有信號處理程序,則內核會使線程調用處理程序 . 大多數(shù)處理程序在線程堆棧上運行 . 如果進程使用sigaltstack(2)提供堆棧,則處理程序可以在備用堆棧上運行,而使用SA_ONSTACK sigaction(2)來設置處理程序 . 內核將一些東西推到所選的堆棧上,并設置一些線程的寄存器 .
要運行處理程序,該線程必須在用戶空間中運行 . 如果線程在內核中運行(可能是系統(tǒng)調用或頁面錯誤),那么在它進入用戶空間之前它不會運行處理程序 . 內核可以中斷一些系統(tǒng)調用,因此線程現(xiàn)在運行處理程序,而不等待系統(tǒng)調用完成 .
信號處理程序是一個C函數(shù),因此內核遵循體系結構調用C函數(shù)的約定 . 每個架構,如arm,i386,powerpc或sparc,都有自己的約定 . 對于powerpc,要調用handler(signum),內核將寄存器r3設置為signum . 內核還將處理程序的返回地址設置為信號trampoline . 返回地址按照慣例進入堆棧或寄存器 .
內核在每個進程中放置一個信號trampoline . 這個trampoline調用sigreturn(2)來恢復線程 . 在內核中,sigreturn(2)從堆棧中讀取一些信息(如保存的寄存器) . 在調用處理程序之前,內核已將此信息推送到堆棧上 . 如果系統(tǒng)調用中斷,內核可能會重新啟動調用(僅當處理程序使用SA_RESTART時),或者使用EINTR失敗,或者返回短讀或寫 .
總結
以上是生活随笔為你收集整理的linux调用信号处理程序后返回,如何在Linux上执行异步信号处理程序?的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: linux kvm安装windows,L
- 下一篇: linux强制格式化,linux – 如
