0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核中信號(hào)詳解

jf_0tjVfeJz ? 來(lái)源:嵌入式ARM和Linux ? 作者:嵌入式ARM和Linux ? 2024-01-13 09:40 ? 次閱讀

  • 1 信號(hào)的角色

    • 1.1 x86/64架構(gòu)信號(hào)定義

    • 1.2 ARM架構(gòu)信號(hào)定義

    • 1.3 RISC-V架構(gòu)信號(hào)定義

    • 1.4 信號(hào)的系統(tǒng)調(diào)用

    • 1.5 信號(hào)工作原理

  • 2 信號(hào)的響應(yīng)行為

  • 3 POSIX信號(hào)和多線程程序

  • 4 與信號(hào)相關(guān)的數(shù)據(jù)結(jié)構(gòu)

    • 4.2.1 x86/Linux2.6.11的定義

    • 4.2.2 x86-64/Linux2.6.11的定義

    • 4.2.3 x86-64/linux5.18.18的定義

    • 4.2.4 ARM/linux5.18.18的定義

    • 4.2.5 RISC-V/linux6.7

    • 4.1 信號(hào)描述符和信號(hào)處理程序描述符

    • 4.2 sigaction數(shù)據(jù)結(jié)構(gòu)

    • 4.3 掛起信號(hào)隊(duì)列

  • 5 信號(hào)數(shù)據(jù)結(jié)構(gòu)的操作函數(shù)

    • 5.1 x86架構(gòu)

    • 5.2 ARM和RISC-V架構(gòu)

Unix最早引入了信號(hào)機(jī)制,允許用戶進(jìn)程間進(jìn)行交互;內(nèi)核也使用信號(hào)通知進(jìn)程某些系統(tǒng)事件。信號(hào)機(jī)制已經(jīng)存在了30年,期間只有一些細(xì)微的變化。

我們首先介紹Linux內(nèi)核如何處理信號(hào),其次討論允許進(jìn)程交換信號(hào)的系統(tǒng)調(diào)用。

1 信號(hào)的角色

信號(hào)是發(fā)送給進(jìn)程,或一組進(jìn)程的非常短的消息。通常,可能僅發(fā)送一個(gè)表示信號(hào)的編碼。標(biāo)準(zhǔn)信號(hào)沒(méi)有參數(shù)等其它信息。

信號(hào)的編碼,在Linux中使用前綴SIG的宏表示。如前面提到的SIGCHLD宏,其展開的值是17,當(dāng)子進(jìn)程停止或終止時(shí),發(fā)送給父進(jìn)程的信號(hào)。SIGSEGV,等于11,當(dāng)進(jìn)程發(fā)生非法內(nèi)存引用時(shí)發(fā)送給進(jìn)程的信號(hào)。

信號(hào)兩個(gè)主要作用:

  1. 使進(jìn)程意識(shí)到發(fā)生了某個(gè)事件
  2. 讓進(jìn)程執(zhí)行信號(hào)處理程序

當(dāng)然,這兩個(gè)目的不是相互排斥的,因?yàn)橥ǔ_M(jìn)程必須對(duì)某些事件做出響應(yīng)(如執(zhí)行服務(wù)例程)。

1.1 x86/64架構(gòu)信號(hào)定義

11-1列出了Linux/i386的前31個(gè)信號(hào)(Unix系統(tǒng)定義的信號(hào),x86架構(gòu),Linux2.6.11linux后續(xù)版本中32/64位的信號(hào)定義統(tǒng)一到了一個(gè)文件中)。某些信號(hào),比如SIGCHLDSIGSTOP與架構(gòu)相關(guān);甚至,還有一些信號(hào)如SIGSTKFLT專門為某些架構(gòu)定義的。

# 信號(hào) 默認(rèn)動(dòng)作 說(shuō)明 POSIX
1 SIGHUP Terminate 掛起控制終端和進(jìn)程 Yes
2 SIGINT Terminate 鍵盤中斷 Yes
3 SIGQUIT Dump 鍵盤退出 Yes
4 SIGILL Dump 非法指令 Yes
5 SIGTRAP Dump 調(diào)試斷點(diǎn) No
6 SIGABRT Dump 異常終止 Yes
6 SIGIOT Dump 等價(jià)于SIGABRT No
7 SIGBUS Dump 總線錯(cuò)誤 No
8 SIGFPE Dump 浮點(diǎn)異常 Yes
9 SIGKILL Terminate 殺死進(jìn)程 Yes
10 SIGUSR1 Terminate 進(jìn)程可用 Yes
11 SIGSEGV Dump 非法內(nèi)存引用 Yes
12 SIGUSR2 Terminate 進(jìn)程可用 Yes
13 SIGPIPE Terminate 管道沒(méi)有讀進(jìn)程使用 Yes
14 SIGALRM Terminate 實(shí)時(shí)時(shí)鐘 Yes
15 SIGTERM Terminate 進(jìn)程終止 Yes
16 SIGSTKFLT Terminate 協(xié)處理器堆棧錯(cuò)誤 No
17 SIGCHLD Ignore 子進(jìn)程停止/終止/被跟蹤時(shí)的信號(hào) Yes
18 SIGCONT Continue 恢復(fù)執(zhí)行 Yes
19 SIGSTOP Stop 停止進(jìn)程執(zhí)行 Yes
20 SIGTSTP Stop 停止tty發(fā)起的進(jìn)程 Yes
21 SIGTTIN Stop 后臺(tái)進(jìn)程需要輸入 Yes
22 SIGTTOU Stop 后臺(tái)進(jìn)程需要輸出 Yes
23 SIGURG Ignore 套接字上的緊急條件 No
24 SIGXCPU Dump 超出CPU時(shí)間限制 No
25 SIGXFSZ Dump 超出文件大小限制 No
26 SIGVTALRM Terminate 用戶態(tài)占用CPU時(shí)間定時(shí)器 No
27 SIGPROF Terminate 用戶態(tài)和內(nèi)核態(tài)占用CPU時(shí)間定時(shí)器 No
28 SIGWINCH Ignore 窗口大小改變 No
29 SIGIO Terminate 異步IO No
29 SIGPOLL Terminate 可輪詢事件(poll) No
30 SIGPWR Terminate 電源失效/重啟動(dòng) No
31 SIGSYS Dump 無(wú)效系統(tǒng)調(diào)用 No
31 SIGUNUSED Dump 等價(jià)于SIGSYS No

除了上表中的常規(guī)信號(hào)之外,POSIX標(biāo)準(zhǔn)還引入了一類新的信號(hào),稱為實(shí)時(shí)信號(hào)Linux中信號(hào)范圍是32~64。實(shí)時(shí)信號(hào)具有以下特性:

  1. 增加了從SIGRTMINSIGRTMAX的實(shí)時(shí)信號(hào),可以通過(guò)sysconf(_SC_RTSIG_MAX)系統(tǒng)函數(shù)獲得當(dāng)前操作系統(tǒng)支持的實(shí)時(shí)信號(hào)的個(gè)數(shù)。但是要注意,一般libc會(huì)對(duì)SIGRTMIN進(jìn)行修改,保留幾個(gè)預(yù)設(shè)的值用于pthread內(nèi)部,比如glibc就保留了3個(gè)值。所以在使用實(shí)時(shí)信號(hào)的時(shí)候,應(yīng)該使用SIGRTMIN+n、SIGRTMAX-n的方式,而不是直接使用數(shù)值。

  2. 實(shí)時(shí)信號(hào)和常規(guī)信號(hào)不一樣,它沒(méi)有明確的含義,而是由使用者自己來(lái)決定如何使用。

  3. 進(jìn)程可以接受多個(gè)相同的實(shí)時(shí)信號(hào),而常規(guī)信號(hào)不能,在常規(guī)信號(hào)沒(méi)有得到處理的時(shí)候,多個(gè)常規(guī)信號(hào)會(huì)被合為一個(gè)。

  4. 實(shí)時(shí)信號(hào)使用sigqueue發(fā)送的時(shí)候,可以攜帶附加的數(shù)據(jù)(int或者pointer)。

  5. 實(shí)時(shí)信號(hào)有時(shí)間順序的概念,所以同樣的實(shí)時(shí)信號(hào)會(huì)按次序被處理。

  6. 信號(hào)實(shí)質(zhì)上是軟中斷,中斷有優(yōu)先級(jí),信號(hào)也有優(yōu)先級(jí)。實(shí)時(shí)信號(hào)具有優(yōu)先的概念,數(shù)值越低的信號(hào)其優(yōu)先級(jí)越高,也就是數(shù)值低的實(shí)時(shí)信號(hào)優(yōu)先得到處理。實(shí)時(shí)信號(hào)和標(biāo)準(zhǔn)信號(hào)的優(yōu)先級(jí),在POSIX中是未定義的,一般來(lái)說(shuō)會(huì)優(yōu)先處理標(biāo)準(zhǔn)信號(hào)。

  7. 實(shí)時(shí)信號(hào)的默認(rèn)行為都一樣,都是結(jié)束當(dāng)前的進(jìn)程,這個(gè)和標(biāo)準(zhǔn)信號(hào)是不一樣的。

盡管Linux內(nèi)核不使用實(shí)時(shí)信號(hào),但是它通過(guò)幾個(gè)特殊的系統(tǒng)調(diào)用完整支持POSIX標(biāo)準(zhǔn)。

Ubuntu 18.04為例,查看Linux系統(tǒng)中使用的信號(hào)方法:

$kill-l
1)SIGHUP2)SIGINT3)SIGQUIT4)SIGILL5)SIGTRAP
6)SIGABRT7)SIGBUS8)SIGFPE9)SIGKILL10)SIGUSR1
11)SIGSEGV12)SIGUSR213)SIGPIPE14)SIGALRM15)SIGTERM
16)SIGSTKFLT17)SIGCHLD18)SIGCONT19)SIGSTOP20)SIGTSTP
21)SIGTTIN22)SIGTTOU23)SIGURG24)SIGXCPU25)SIGXFSZ
26)SIGVTALRM27)SIGPROF28)SIGWINCH29)SIGIO30)SIGPWR
31)SIGSYS34)SIGRTMIN35)SIGRTMIN+136)SIGRTMIN+237)SIGRTMIN+3
38)SIGRTMIN+439)SIGRTMIN+540)SIGRTMIN+641)SIGRTMIN+742)SIGRTMIN+8
43)SIGRTMIN+944)SIGRTMIN+1045)SIGRTMIN+1146)SIGRTMIN+1247)SIGRTMIN+13
48)SIGRTMIN+1449)SIGRTMIN+1550)SIGRTMAX-1451)SIGRTMAX-1352)SIGRTMAX-12
53)SIGRTMAX-1154)SIGRTMAX-1055)SIGRTMAX-956)SIGRTMAX-857)SIGRTMAX-7
58)SIGRTMAX-659)SIGRTMAX-560)SIGRTMAX-461)SIGRTMAX-362)SIGRTMAX-2
63)SIGRTMAX-164)SIGRTMAX

1.2 ARM架構(gòu)信號(hào)定義

下圖右邊是ARM架構(gòu)與x86架構(gòu)信號(hào)定義的比較圖(左邊是x86架構(gòu),右邊是ARM架構(gòu))。通過(guò)對(duì)比發(fā)現(xiàn),ARM架構(gòu)比x86架構(gòu)多了一個(gè)SIGSWI信號(hào)。在對(duì)內(nèi)核源代碼進(jìn)行進(jìn)一步調(diào)查后,發(fā)現(xiàn)唯一提到SIGSWI(不包括聲明本身)的是文件Linux 5.18.18中,位于tools/perf/trace/beauty/signum.c。具體代碼中只有在打印信號(hào)的時(shí)候用,貌似已經(jīng)從內(nèi)核中移除。)。一些奇怪的基于ARM 的操作系統(tǒng)(RISCOS)使用這種方式與其模擬器進(jìn)行通信。它被稱為Arthur OS。

ae816fa2-b13a-11ee-8b88-92fbcf53809c.png

1.3 RISC-V架構(gòu)信號(hào)定義

RISC-V架構(gòu)信號(hào)定義如下面所示,Linux 6.7內(nèi)核,文件位于/include/uapi/asm-generic/signal.h。信號(hào)的定義直接使用了標(biāo)準(zhǔn)的接口規(guī)范。

#define_NSIG64
//...省略
#defineSIGHUP1
#defineSIGINT2
//...省略
#defineSIGPWR30
#defineSIGSYS31
#defineSIGUNUSED31

/*用戶進(jìn)程不能認(rèn)為這些是常數(shù)*/
#defineSIGRTMIN32
#ifndefSIGRTMAX
#defineSIGRTMAX_NSIG
#endif

所以說(shuō),對(duì)于Linux信號(hào)來(lái)說(shuō),不管是x86架構(gòu),ARM架構(gòu),還是RISC-V,都是統(tǒng)一的,沒(méi)有什么變化。

1.4 信號(hào)的系統(tǒng)調(diào)用

Linux提供了一些系統(tǒng)調(diào)用,允許編程者發(fā)送信號(hào),并決定如何響應(yīng)接收到的信號(hào)。下表列出了這些系統(tǒng)調(diào)用:

系統(tǒng)調(diào)用 描述
kill() 發(fā)送信號(hào)給線程組
tkill() 發(fā)送信號(hào)給進(jìn)程
tgkill() 發(fā)送信號(hào)給特定線程組中的進(jìn)程
sigaction() 設(shè)定信號(hào)的行為
signal() 與sigaction()類似
sigpending() 檢查是否為掛起信號(hào)
sigprocmask() 修改阻塞信號(hào)
sigsuspend() 等待信號(hào)
rt_sigaction() 設(shè)定實(shí)時(shí)信號(hào)的行為
rt_sigpending() 檢查是否為掛起的實(shí)時(shí)信號(hào)
rt_sigprocmask() 修改阻塞的實(shí)時(shí)信號(hào)
rt_sigqueueinfo() 發(fā)送實(shí)時(shí)信號(hào)給線程組
rt_sigsuspend() 等待實(shí)時(shí)信號(hào)
rt_sigtimedwait() 與rt_sigsuspend()類似

1.5 信號(hào)工作原理

信號(hào)的一個(gè)重要特性是,可能會(huì)在任何時(shí)候傳遞給進(jìn)程。發(fā)送給沒(méi)有在執(zhí)行狀態(tài)的進(jìn)程,就需要保存該信號(hào),以便進(jìn)程恢復(fù)執(zhí)行時(shí)處理它。阻塞信號(hào)要求在解除阻塞之前延緩信號(hào)的傳遞。

因此,Linux將內(nèi)核的傳遞分為了兩個(gè)階段:

  • 信號(hào)產(chǎn)生

    內(nèi)核更新目標(biāo)進(jìn)程的數(shù)據(jù)結(jié)構(gòu),表達(dá)一個(gè)新信號(hào)要被發(fā)送。

  • 信號(hào)傳遞

    內(nèi)核通過(guò)改變目標(biāo)進(jìn)程的狀態(tài),且執(zhí)行指定信號(hào)處理程序,以強(qiáng)制其響應(yīng)信號(hào),

每個(gè)信號(hào)最多傳遞一次。信號(hào)是消耗性資源:一旦它們被傳遞,所有進(jìn)程描述符中跟信號(hào)有關(guān)的數(shù)據(jù)引用都將取消。

產(chǎn)生還沒(méi)有傳遞的信號(hào),稱為掛起信號(hào)。任何時(shí)候,一個(gè)進(jìn)程只能存在一個(gè)給定類型的掛起信號(hào);同一個(gè)進(jìn)程的同類掛起信號(hào)會(huì)被拋棄。但是,實(shí)時(shí)信號(hào)與此不同:可以同時(shí)存在多個(gè)同類型的掛起信號(hào)。

信號(hào)產(chǎn)生還沒(méi)有被傳遞這段時(shí)間,通常存在于以下時(shí)間段:

  • 信號(hào)通常只傳遞給當(dāng)前正在運(yùn)行的進(jìn)程(current)。

  • 進(jìn)程可以有選擇地阻塞信號(hào)。這種情況下,進(jìn)程不會(huì)接收信號(hào),除非解除阻塞。

  • 執(zhí)行信號(hào)處理程序時(shí),進(jìn)程通常屏蔽掉響應(yīng)的信號(hào)(例如,在信號(hào)處理程序執(zhí)行完之前自動(dòng)阻塞該信號(hào))。也就是說(shuō),信號(hào)處理程序不會(huì)被正在處理的信號(hào)打斷,所以,信號(hào)處理程序不需要考慮可重入的問(wèn)題。

盡管信號(hào)的概念非常簡(jiǎn)單,內(nèi)核實(shí)現(xiàn)卻相當(dāng)復(fù)雜。內(nèi)核必須:

  • 記住哪些信號(hào)被哪個(gè)進(jìn)場(chǎng)阻塞。

  • 當(dāng)從內(nèi)核態(tài)切換到用戶態(tài)時(shí),檢查該進(jìn)程是否有信號(hào)需要處理。這通常發(fā)生在每次定時(shí)器中斷時(shí)(大約幾個(gè)毫秒一次)。

  • 判斷該信號(hào)是否被忽略。滿足忽略的條件如下:

    • 目標(biāo)進(jìn)程沒(méi)有被其它進(jìn)程追蹤(也就是進(jìn)程描述符中的PT_PTRACED標(biāo)志等于0)。
    • 信號(hào)沒(méi)有被目標(biāo)進(jìn)程阻塞。
    • 信號(hào)正在被目標(biāo)忽略。(可以是進(jìn)程顯式忽略,也可以是信號(hào)的默認(rèn)行為是忽略且進(jìn)程沒(méi)有更改它)
  • 處理信號(hào),可能涉及到在進(jìn)程執(zhí)行的任何時(shí)候切換到信號(hào)處理程序,且需要在處理程序返回時(shí)恢復(fù)其原始執(zhí)行上下文。

此外,Linux必須考慮到BSDSystem V信號(hào)采用的不同語(yǔ)義,它必須遵循相當(dāng)復(fù)雜的POSIX要求。

2 信號(hào)的響應(yīng)行為

信號(hào)的響應(yīng)方式有3種:

  1. 忽略信號(hào)
  • Terminate

    殺死進(jìn)程。

  • Dump

    殺死進(jìn)程,如果可能的話創(chuàng)建一個(gè)包含其上下文的核心轉(zhuǎn)儲(chǔ)文件。該文件主要用于調(diào)試目的。

  • Ignore

    忽略信號(hào)。

  • Stop

    停止進(jìn)程。例如將進(jìn)程置為TASK_STOPPED狀態(tài)。

  • Continue

    繼續(xù)進(jìn)程(TASK_STOPPED),將其置于TASK_RUNNING狀態(tài)。

  1. 執(zhí)行信號(hào)的默認(rèn)行為。默認(rèn)行為是內(nèi)核預(yù)定義好的,如下所示:
  1. 捕獲信號(hào),執(zhí)行自定義的信號(hào)處理程序。

注意,阻塞信號(hào)不同于忽略信號(hào)。只要信號(hào)被阻塞,就不會(huì)傳遞它。而忽略信號(hào)總是傳遞它,只是不執(zhí)行響應(yīng)動(dòng)作。

SIGKILLSIGSTOP信號(hào)不能被忽略,捕獲或阻塞。它們的默認(rèn)動(dòng)作總是會(huì)被執(zhí)行。因此,SIGKILLSIGSTOP信號(hào)給予合適權(quán)限的用戶可以終止、停止每個(gè)進(jìn)程(這兒有兩個(gè)例外:不能向進(jìn)程0-swapper發(fā)送信號(hào),并且發(fā)送給進(jìn)程1-init的信號(hào)總是被丟棄。因此,進(jìn)程0永遠(yuǎn)不會(huì)死亡,而進(jìn)程1只有在init終止時(shí)才會(huì)死亡。)。

如果信號(hào)造成內(nèi)核殺死進(jìn)程,那么對(duì)于給定進(jìn)程是非常致命的,比如SIGKILL。默認(rèn)行為為Terminate的信號(hào)且未被進(jìn)程捕獲,對(duì)于該進(jìn)程來(lái)說(shuō)也是致命的。但是,如果信號(hào)被捕獲,而其處理程序終止進(jìn)程則不是致命的,因?yàn)檫M(jìn)程自己選擇的終止,不是內(nèi)核殺死的。

3 POSIX信號(hào)和多線程程序

POSIX 1003.1標(biāo)準(zhǔn)對(duì)多線程應(yīng)用程序的信號(hào)處理有嚴(yán)格的要求:

  • 多線程應(yīng)用程序中所有線程共享信號(hào)處理程序;但是,每個(gè)線程必須具有自己的掛起信號(hào)和阻塞信號(hào)的位數(shù)組。

  • kill()sigqueue()POSIX庫(kù)函數(shù)必須發(fā)送信號(hào)給整個(gè)多線程應(yīng)用,而不是某個(gè)特定的線程。內(nèi)核生成的所有信號(hào)(如SIGCHLD、SIGINTSIGQUIT)都是如此。

  • 發(fā)送給多線程應(yīng)用的信號(hào)只被傳遞給一個(gè)線程,由內(nèi)核在沒(méi)有阻塞該信號(hào)的線程中任意選擇。

  • 如果致命信號(hào)發(fā)送給多線程應(yīng)用,內(nèi)核將殺死應(yīng)用程序的所有線程,而不僅僅是信號(hào)傳遞給的那個(gè)線程。

為了遵循POSIX標(biāo)準(zhǔn),Linux 2.6內(nèi)核將多線程應(yīng)用程序?qū)崿F(xiàn)為屬于同一線程組的一組輕量級(jí)進(jìn)程。

本文中的線程組是廣義的,甚至可以使傳統(tǒng)意義上的單進(jìn)程。術(shù)語(yǔ)進(jìn)程表示傳統(tǒng)意義上的進(jìn)程或輕量級(jí)進(jìn)程(線程組中的某個(gè)成員)。

此外,如果信號(hào)被發(fā)送給一個(gè)特定的進(jìn)程,則是私有的;如果發(fā)送給整個(gè)線程組,則是共享的。

4 與信號(hào)相關(guān)的數(shù)據(jù)結(jié)構(gòu)

為了追蹤進(jìn)程或線程組的信號(hào)狀態(tài),內(nèi)核在進(jìn)程描述符中提供了幾個(gè)可訪問(wèn)的數(shù)據(jù)結(jié)構(gòu)。重要的數(shù)據(jù)結(jié)構(gòu)如下所示:

ae9ee96a-b13a-11ee-8b88-92fbcf53809c.png

其中,進(jìn)程描述符中與信號(hào)處理相關(guān)的數(shù)據(jù)字段如下所示:

數(shù)據(jù)類型 名稱 描述
struct signal_struct * signal 指向進(jìn)程的信號(hào)描述符
struct sighand_struct * sighand 指向進(jìn)程的信號(hào)處理程序描述符
sigset_t blocked 阻塞信號(hào)掩碼
sigset_t real_blocked 阻塞信號(hào)臨時(shí)掩碼(rt_sigtimedwait())系統(tǒng)調(diào)用使用
struct sigpending pending 私有掛起信號(hào)
unsigned long sas_ss_sp 備選信號(hào)處理程序堆棧的地址

blocked存儲(chǔ)了被進(jìn)程屏蔽掉的信號(hào)。數(shù)據(jù)類型為sigset_t,是一個(gè)位數(shù)組,每一位代表一類信號(hào):

typedefstruct{
unsignedlongsig[2];
}sigset_t;

因?yàn)?code style="color:rgb(30,107,184);font-size:14px;line-height:1.8em;letter-spacing:0em;background:rgba(27,31,35,.05) none no-repeat scroll 0% 0%;width:auto;height:auto;margin-left:2px;margin-right:2px;padding:2px 4px;border-style:none;border-width:3px;border-color:rgba(0,0,0,.4) rgba(0,0,0,.4);font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;">32位系統(tǒng)的unsigned long32位,信號(hào)最大數(shù)量是64(用_NSIG宏表示)。因?yàn)闆](méi)有信號(hào)是0,所以,信號(hào)值等于sigset_t中位索引1。具體可以參考前面列出的表。

4.1 信號(hào)描述符和信號(hào)處理程序描述符

進(jìn)程描述符中的signal字段指向信號(hào)描述符,類型為signal_struct,用來(lái)記錄共享掛起信號(hào)。此外,信號(hào)描述符還有一些與信號(hào)處理不太相關(guān)的字段,如rlim(進(jìn)程資源限制),或pgrpsession字段,分別存儲(chǔ)線程組領(lǐng)導(dǎo)者的PID和進(jìn)程中會(huì)話領(lǐng)導(dǎo)者的PID。事實(shí)上,我們?cè)趯W(xué)習(xí)clone(),fork(),和vfork()系統(tǒng)調(diào)用一節(jié)時(shí)了解到,同一線程組中的所有進(jìn)程共享信號(hào)描述符,也就是說(shuō),通過(guò)clone()系統(tǒng)調(diào)用,并設(shè)置CLONE_THREAD標(biāo)志,創(chuàng)建的所有進(jìn)程,其信號(hào)描述符中所有字段必須相同。

信號(hào)描述符中與信號(hào)處理相關(guān)的字段,如下表所示:

類型 變量 描述
atomic_t count 信號(hào)描述符的使用計(jì)數(shù)器
atomic_t live 線程組中活動(dòng)進(jìn)程的數(shù)量
wait_queue_head_t wait_chldexit wait4()系統(tǒng)調(diào)用中休眠進(jìn)程的等待隊(duì)列
struct task_struct * curr_target 線程組中接收到信號(hào)的最后一個(gè)進(jìn)程的描述符
struct sigpending shared_pending 共享掛起信號(hào)的數(shù)據(jù)結(jié)構(gòu)
int group_exit_code 線程組的進(jìn)程終止碼
struct task_struct * group_exit_task 殺死整個(gè)線程組時(shí)使用
int notify_count 殺死整個(gè)線程組時(shí)使用
int group_stop_count 停止整個(gè)線程組時(shí)使用
unsigned int flags 傳遞修改進(jìn)程狀態(tài)的信號(hào)時(shí)使用的標(biāo)志

除了信號(hào)描述符,每個(gè)進(jìn)程還有一個(gè)信號(hào)處理描述符,數(shù)據(jù)結(jié)構(gòu)為sighand_struct,其描述了線程組怎樣處理信號(hào)。其字段如下所示:

類型 變量 描述
atomic_t count 信號(hào)處理程序描述符的使用計(jì)數(shù)器
struct k_sigaction[64] action 指定傳遞信號(hào)時(shí)要執(zhí)行的動(dòng)作的結(jié)構(gòu)數(shù)組
spinlock_t siglock 包含信號(hào)和信號(hào)處理程序等描述符的自旋鎖

正如先前提到的,使用clone()CLONE_SIGHAND標(biāo)志創(chuàng)建的進(jìn)程們共享信號(hào)處理描述符。所以,count字段記錄了共享信號(hào)處理描述符的進(jìn)程數(shù)。在POSIX多線程應(yīng)用中,線程組中的所有輕量級(jí)進(jìn)程引用相同的信號(hào)描述符和相同的信號(hào)處理描述符。

4.2 sigaction數(shù)據(jù)結(jié)構(gòu)

有些架構(gòu)可能會(huì)將信號(hào)的某些屬性僅對(duì)內(nèi)核可見(jiàn)。因此,存儲(chǔ)在k_sigaction中的信號(hào)屬性,既包含了對(duì)用戶態(tài)隱藏的屬性,也包含了用戶態(tài)所有可見(jiàn)的屬性。事實(shí)上,在x86平臺(tái)上,所有的信號(hào)屬性對(duì)用戶態(tài)都是可見(jiàn)的。

因此,k_sigaction結(jié)構(gòu)簡(jiǎn)化為一個(gè)類型為sigactionsa結(jié)構(gòu),它包含如下字段*:

用戶態(tài)應(yīng)用程序用來(lái)給signal()sigaction()系統(tǒng)調(diào)用傳遞參數(shù)的sigaction數(shù)據(jù)結(jié)構(gòu)與內(nèi)核使用的數(shù)據(jù)結(jié)構(gòu)略有不同。

  • sa_handler

    該字段指定要執(zhí)行的動(dòng)作類型;可以是信號(hào)處理程序的指針,SIG_DFL(值為0,執(zhí)行默認(rèn)行為),或SIG_IGN(值為1,忽略信號(hào))。

  • sa_flags

    如何處理處理信號(hào)的標(biāo)志,下表列出了其中的一些。

    因?yàn)闅v史原因,這些標(biāo)志和irqaction具有一樣的前綴SA_;然而,兩組標(biāo)志沒(méi)有任何關(guān)系。

  • sa_mask

    類型為sigset_t,用來(lái)指定在運(yùn)行信號(hào)處理程序時(shí)屏蔽掉的信號(hào)。

sa_flags值和意義

標(biāo)志名稱 描述
SA_NOCLDSTOP 僅適用于SIGCHLD;當(dāng)進(jìn)程停止時(shí)不向父進(jìn)程發(fā)送SIGCHLD
SA_NOCLDWAIT 僅適用于SIGCHLD;當(dāng)進(jìn)程終止時(shí)不會(huì)創(chuàng)建zombie僵尸進(jìn)程
SA_SIGINFO 向信號(hào)處理程序提供額外的信息(查看稍后的改變信號(hào)動(dòng)作)
SA_ONSTACK 為信號(hào)處理程序使用替代堆棧(查看稍后的捕捉信號(hào)一節(jié))
SA_RESTART 中斷的系統(tǒng)調(diào)用自動(dòng)重啟(查看稍后的`系統(tǒng)調(diào)用的重新執(zhí)行)
SA_NODEFER,
SA_NOMASK
在執(zhí)行信號(hào)處理程序時(shí)不屏蔽信號(hào)
SA_RESETHAND,
SA_ONESHOT
在執(zhí)行信號(hào)處理程序后重置為默認(rèn)操作
4.2.1 x86/Linux2.6.11的定義
#ifdef__KERNEL__
structold_sigaction{
__sighandler_tsa_handler;
old_sigset_tsa_mask;
unsignedlongsa_flags;
__sigrestore_tsa_restorer;
};

structsigaction{
__sighandler_tsa_handler;
unsignedlongsa_flags;
__sigrestore_tsa_restorer;
sigset_tsa_mask;/*masklastforextensibility*/
};

structk_sigaction{
structsigactionsa;
};
#else
/*這是為了迎合libc庫(kù)的實(shí)現(xiàn)*/
structsigaction{
union{
__sighandler_t_sa_handler;
void(*_sa_sigaction)(int,structsiginfo*,void*);
}_u;
sigset_tsa_mask;
unsignedlongsa_flags;
void(*sa_restorer)(void);
};

#definesa_handler_u._sa_handler
#definesa_sigaction_u._sa_sigaction
#endif/*__KERNEL__*/
4.2.2 x86-64/Linux2.6.11的定義
structsigaction{
__sighandler_tsa_handler;
unsignedlongsa_flags;
__sigrestore_tsa_restorer;
sigset_tsa_mask;/*masklastforextensibility*/
};

structk_sigaction{
structsigactionsa;
};
4.2.3 x86-64/linux5.18.18的定義

較高版本中的內(nèi)核中,將k_sigaction定義到了一個(gè)統(tǒng)一的文件中(include/linux/signal_types.h

structsigaction{
#ifndef__ARCH_HAS_IRIX_SIGACTION
__sighandler_tsa_handler;
unsignedlongsa_flags;
#else
unsignedintsa_flags;
__sighandler_tsa_handler;
#endif
#ifdef__ARCH_HAS_SA_RESTORER
__sigrestore_tsa_restorer;
#endif
sigset_tsa_mask;/*masklastforextensibility*/
};

structk_sigaction{
structsigactionsa;
#ifdef__ARCH_HAS_KA_RESTORER
__sigrestore_tka_restorer;
#endif
};

為了兼容libc庫(kù),需要根據(jù)架構(gòu)進(jìn)行一些定義:

#ifndef__KERNEL__
/*這是為了迎合libc庫(kù)的實(shí)現(xiàn)*/
#ifdef__i386__

structsigaction{
union{
__sighandler_t_sa_handler;
void(*_sa_sigaction)(int,structsiginfo*,void*);
}_u;
sigset_tsa_mask;
unsignedlongsa_flags;
void(*sa_restorer)(void);
};

#definesa_handler_u._sa_handler
#definesa_sigaction_u._sa_sigaction

#else/*__i386__*/

structsigaction{
__sighandler_tsa_handler;
unsignedlongsa_flags;
__sigrestore_tsa_restorer;
sigset_tsa_mask;/*masklastforextensibility*/
};

#endif/*!__i386__*/
#endif/*!__KERNEL__*/
4.2.4 ARM/linux5.18.18的定義

ARM架構(gòu)下內(nèi)核中數(shù)據(jù)結(jié)構(gòu)與x86架構(gòu)相同,但是,為了兼容libc,不得不定義一些特殊的結(jié)構(gòu):

#ifndef__KERNEL__
/*這是為了迎合libc庫(kù)的實(shí)現(xiàn)*/
structsigaction{
union{
__sighandler_t_sa_handler;
void(*_sa_sigaction)(int,structsiginfo*,void*);
}_u;
sigset_tsa_mask;
unsignedlongsa_flags;
void(*sa_restorer)(void);
};

#definesa_handler_u._sa_handler
#definesa_sigaction_u._sa_sigaction

#endif/*__KERNEL__*/
4.2.5 RISC-V/linux6.7

最新版本內(nèi)核中沒(méi)有變化,RISC-V相關(guān)實(shí)現(xiàn)與ARM架構(gòu)相同,只是,取消了聯(lián)合體復(fù)雜的實(shí)現(xiàn)(這就是后發(fā)優(yōu)勢(shì)):

#ifndef__KERNEL__
structsigaction{
__sighandler_tsa_handler;
unsignedlongsa_flags;
#ifdefSA_RESTORER
__sigrestore_tsa_restorer;
#endif
sigset_tsa_mask;/*masklastforextensibility*/
};
#endif

4.3 掛起信號(hào)隊(duì)列

正如前面所述,某些系統(tǒng)可以產(chǎn)生信號(hào):kill()rt_sigqueueinfo()發(fā)送信號(hào)到整個(gè)線程組,而tkill()tgkill()發(fā)送信號(hào)到某個(gè)特定的進(jìn)程。

為了記錄當(dāng)前哪些信號(hào)被掛起,內(nèi)核給每個(gè)進(jìn)程提供了兩個(gè)掛起信號(hào)隊(duì)列:

  • 共享掛起信號(hào)隊(duì)列,掛載到信號(hào)描述符的shared_pending字段,存儲(chǔ)整個(gè)線程組的掛起信號(hào)。

  • 私有掛起信號(hào)隊(duì)列,掛載到進(jìn)程描述符的pending字段,存儲(chǔ)進(jìn)程(輕量級(jí))自己的掛起信號(hào)。

掛起信號(hào)隊(duì)列的元素是類型為sigpending的數(shù)據(jù)結(jié)構(gòu),定義如下:

structsigpending{
structlist_headlist;
sigset_tsignal;
}

signal字段是一個(gè)位數(shù)組,每一位代表一個(gè)掛起信號(hào),而list字段是雙向鏈表的頭,該表頭指向sigqueue數(shù)據(jù)結(jié)構(gòu)組成的鏈表,sigqueue字段定義如下表所示:

類型 變量 描述
struct list_head list 掛起信號(hào)隊(duì)列的鏈表鏈接
spinlock_t * lock 信號(hào)處理描述符的siglock字段的指針
int flags sigqueue數(shù)據(jù)結(jié)構(gòu)中的標(biāo)志
siginfo_t info 描述發(fā)送信號(hào)的事件信息
struct user_struct * user 指向進(jìn)程擁有者的用戶數(shù)據(jù)結(jié)構(gòu)

其中,siginfo_t的大小為128字節(jié),描述特定信號(hào)事件的信息;它包含以下字段:

  • si_signo

    信號(hào)編碼。

  • si_errno

    產(chǎn)生信號(hào)的指令的錯(cuò)誤編碼,如果是0則沒(méi)有錯(cuò)誤。

  • si_code

    標(biāo)識(shí)發(fā)送信號(hào)方的編碼(參加表11-8

    11-8。最重要的信號(hào)發(fā)送方編碼

    編碼名稱 發(fā)送方
    SI_USER kill()raise()(查看稍后的與信號(hào)處理相關(guān)的系統(tǒng)調(diào)用)
    SI_KERNEL 通用內(nèi)核函數(shù)產(chǎn)生的信號(hào)
    SI_QUEUE sigqueue()(查看稍后的與信號(hào)處理相關(guān)的系統(tǒng)調(diào)用)
    SI_TIMER 定時(shí)器到時(shí)
    SI_ASYNCIO 異步IO完成
    SI_TKILL tkill()tgkill()(查看稍后的與信號(hào)處理相關(guān)的系統(tǒng)調(diào)用)
  • _sifields

    一個(gè)聯(lián)合體數(shù)據(jù)類型,根據(jù)信號(hào)類型存儲(chǔ)信息。例如是SIGKILL信號(hào),siginfo_t記錄發(fā)送進(jìn)程的PIDUID;如果是SIGSEGV,則記錄產(chǎn)生信號(hào)時(shí)訪問(wèn)的內(nèi)存地址。

5 信號(hào)數(shù)據(jù)結(jié)構(gòu)的操作函數(shù)

為了方便處理信號(hào),內(nèi)核提供了幾個(gè)函數(shù)和宏,如下所示。其中,set是指向sigset_t變量的指針,nsig是信號(hào)值,mask是一個(gè)unsigned long類型的位掩碼。

  • sigemptyset(set)/sigfillset(set)

    設(shè)置sigset_t變量的位為01。

  • sigaddset(set,nsig)/sigdelset(set,nsig)

    設(shè)置sigset_t變量中指定信號(hào)nsig10。事實(shí)上,sigaddset()可以簡(jiǎn)化為

    set->sig[(nsig-1)/32]|=1UL<1)%32);
    

    sigdelset()簡(jiǎn)化為

    set->sig[(nsig-1)/32]&=~(1UL<1)%32));
    
  • sigaddsetmask(set,mask)/sigdelsetmask(set,mask)

    設(shè)置sigset_t類型變量的位掩碼為10。

    set->sig[0]|=mask;
    

    and to:

    set->sig[0]&=~mask;
    
  • sigismember(set,nsig)

    返回信號(hào)nsigsigset_t變量中的對(duì)應(yīng)位。實(shí)際可以簡(jiǎn)化為:

    return1&(set->sig[(nsig-1)/32]>>((nsig-1)%32));
    
  • sigmask(nsig)

    產(chǎn)生信號(hào)nsig的位索引。換句話說(shuō),如果內(nèi)核需要設(shè)置、清除或測(cè)試sigset_t類型變量中的信號(hào)對(duì)應(yīng)位,可以通過(guò)該宏可以導(dǎo)出正確的位。

  • sigandsets(d,s1,s2)/sigorsets(d,s1,s2)/signandsets(d,s1,s2)

    對(duì)s1s2執(zhí)行邏輯AND、ORNAND操作,結(jié)果保存到d中。

  • sigtestsetmask(set,mask)

    如果變量的相應(yīng)位掩碼為1,則返回1;否則返回0。只有在信號(hào)1~32之間使用。

  • siginitset(set,mask)

    mask的位初始化sigset_t變量中1 ~ 32信號(hào)對(duì)應(yīng)的低位,清除33 ~ 63信號(hào)對(duì)應(yīng)位。

  • siginitsetinv(set,mask)

    mask的補(bǔ)碼初始化sigset_t變量1~32信號(hào)對(duì)應(yīng)的低位,并設(shè)置33~63信號(hào)對(duì)應(yīng)的位。

  • signal_pending(p)

    判斷由p指向的進(jìn)程描述符是否具有非阻塞的掛起信號(hào),如果有,返回1true);如果沒(méi)有,則返回0false)。該函數(shù)是通過(guò)對(duì)進(jìn)程的TIF_SIGPENDING標(biāo)志進(jìn)行檢查實(shí)現(xiàn)的。

  • recalc_sigpending_tsk(t)/recalc_sigpending()

    第一個(gè)函數(shù)檢查t指向的進(jìn)程描述符中是否有掛起信號(hào)(通過(guò)檢查t->pending->signal字段實(shí)現(xiàn)),或者檢查該進(jìn)程所屬線程組是否有掛起信號(hào)(通過(guò)檢查t-> signal->shared_pending->signal實(shí)現(xiàn))。該函數(shù)隨后設(shè)置t->thread_info->flags中的TIF_SIGPENDING標(biāo)志位。recalc_sigpending()等價(jià)于recalc_sigpending_tsk(current)。

  • rm_from_queue(mask,q)

    從掛起信號(hào)隊(duì)列q中移除mask位掩碼中對(duì)應(yīng)的掛起信號(hào)。

  • flush_sigqueue(q)

    從掛起信號(hào)隊(duì)列q中移除所有掛起信號(hào)。

  • flush_signals(t)

    刪除發(fā)送給進(jìn)程的所有信號(hào)(t指向進(jìn)程描述符)。實(shí)現(xiàn)方式是清除t->thread_info->flagsTIF_SIGPENDING標(biāo)志,并分別對(duì)t->pendingt->signal->shared_ pending隊(duì)列調(diào)用flush_sigqueue()。

5.1 x86架構(gòu)

較新的內(nèi)核版本(比如,v5.18.18v6.7)中,這些函數(shù)都已經(jīng)作了統(tǒng)一處理,位于文件include/linux/signal.h中。但是,x86架構(gòu)體系的i386它的實(shí)現(xiàn)使用了匯編指令(為了效率),比如:

staticinlineint__gen_sigismember(sigset_t*set,int_sig)
{
boolret;
asm("btl%2,%1"CC_SET(c)
:CC_OUT(c)(ret):"m"(*set),"Ir"(_sig-1));
returnret;
}

__gen_sigismembersigismember的一個(gè)底層實(shí)現(xiàn),其中用到了匯編指令btl(將寄存器的位進(jìn)行比較,如果該位被設(shè)置則置為1,則CC_SET(c)條件碼會(huì)被設(shè)置為真,否則為假)。所以,i386有一部分設(shè)置信號(hào)的函數(shù)定義獨(dú)自一個(gè)文件(/arch/x86/include/asm/signal.h)。

5.2 ARM和RISC-V架構(gòu)

x86-64ARMRISC-V架構(gòu)的函數(shù)定義都位于include/linux/signal.h文件中,是統(tǒng)一實(shí)現(xiàn)。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5045

    文章

    18816

    瀏覽量

    298459
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1336

    瀏覽量

    40083
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207895
  • 信號(hào)
    +關(guān)注

    關(guān)注

    11

    文章

    2739

    瀏覽量

    76172

原文標(biāo)題:Linux內(nèi)核-信號(hào)的基本理解

文章出處:【微信號(hào):嵌入式ARM和Linux,微信公眾號(hào):嵌入式ARM和Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    linux內(nèi)核信號(hào)是如何處理的?看完全懂了……

    本文簡(jiǎn)單介紹下Linux信號(hào)處理機(jī)制,為介紹二進(jìn)制翻譯下信號(hào)處理機(jī)制做一個(gè)鋪墊。 本文主要參考書目《Linux內(nèi)核源代碼情景分析》《獨(dú)辟蹊徑
    的頭像 發(fā)表于 11-16 05:11 ?1.4w次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>信號(hào)</b>是如何處理的?看完全懂了……

    一文詳解Linux內(nèi)核源碼組織結(jié)構(gòu)

    概要:本文內(nèi)容包含Linux源碼樹結(jié)構(gòu)分析、Linux Makefile分析、Kconfig文件分析、Linux內(nèi)核配置選項(xiàng)分析。這些知識(shí)是為了理解
    的頭像 發(fā)表于 05-10 19:28 ?5612次閱讀

    Linux內(nèi)核中信號(hào)的傳遞過(guò)程

    前面我們已經(jīng)介紹了內(nèi)核注意到信號(hào)的到來(lái),調(diào)用相關(guān)函數(shù)更新進(jìn)程描述符以便進(jìn)程接收處理信號(hào)。但是,如果目標(biāo)進(jìn)程此時(shí)沒(méi)有運(yùn)行,內(nèi)核則推遲傳遞信號(hào)。
    的頭像 發(fā)表于 01-17 09:51 ?869次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>中信號(hào)</b>的傳遞過(guò)程

    Linux內(nèi)核地址映射模型與Linux內(nèi)核高端內(nèi)存詳解

    Linux 操作系統(tǒng)和驅(qū)動(dòng)程序運(yùn)行在內(nèi)核空間,應(yīng)用程序運(yùn)行在用戶空間,兩者不能簡(jiǎn)單地使用指針傳遞數(shù)據(jù),因?yàn)?b class='flag-5'>Linux使用的虛擬內(nèi)存機(jī)制,用戶空間的數(shù)據(jù)可能被換出,當(dāng)內(nèi)核空間使用用戶空間
    發(fā)表于 05-08 10:33 ?3401次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>地址映射模型與<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>高端內(nèi)存<b class='flag-5'>詳解</b>

    詳解Linux內(nèi)核搶占實(shí)現(xiàn)機(jī)制

    本文詳解Linux內(nèi)核搶占實(shí)現(xiàn)機(jī)制。首先介紹了內(nèi)核搶占和用戶搶占的概念和區(qū)別,接著分析了不可搶占內(nèi)核的特點(diǎn)及實(shí)時(shí)系統(tǒng)中實(shí)現(xiàn)
    發(fā)表于 08-06 06:16

    Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解:基于最新的Linux 4.0內(nèi)核

    Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解:基于最新的Linux 4.0內(nèi)核
    發(fā)表于 08-31 12:29

    linux2.6內(nèi)核設(shè)備驅(qū)動(dòng)模型精華

    linux 內(nèi)核驅(qū)動(dòng)部分詳解
    發(fā)表于 04-27 10:43 ?20次下載

    Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解》第4章、Linux內(nèi)核模塊

    Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解》第4章、Linux內(nèi)核模塊
    發(fā)表于 10-27 14:15 ?0次下載
    《<b class='flag-5'>Linux</b>設(shè)備驅(qū)動(dòng)開發(fā)<b class='flag-5'>詳解</b>》第4章、<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>模塊

    Linux內(nèi)核配置系統(tǒng)詳解

    隨著 Linux 操作系統(tǒng)的廣泛應(yīng)用,特別是 Linux 在嵌入式領(lǐng)域的發(fā)展,越來(lái)越多的人開始投身到 Linux 內(nèi)核級(jí)的開發(fā)中。面對(duì)日益龐大的 L
    發(fā)表于 11-01 15:45 ?4次下載

    Linux內(nèi)核編譯過(guò)程詳解

    Linux內(nèi)核編譯過(guò)程詳解(kernel2.6.7) 花了幾天才編譯成功kernel2.6.7,其過(guò)程真可謂艱辛。古語(yǔ)有云:苦盡甘來(lái)!現(xiàn)在終于可以樂(lè)上一陣了。由于許多朋友對(duì)操作的順序及某些重要的配置
    發(fā)表于 11-07 11:16 ?4次下載

    linux內(nèi)核rcu機(jī)制詳解

    Linux內(nèi)核源碼當(dāng)中,關(guān)于RCU的文檔比較齊全,你可以在 /Documentation/RCU/ 目錄下找到這些文件。Paul E. McKenney 是內(nèi)核中RCU源碼的主要實(shí)現(xiàn)者,他也寫了很多RCU方面的文章。今天我們而主
    發(fā)表于 11-13 16:47 ?8672次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b>rcu機(jī)制<b class='flag-5'>詳解</b>

    LINUX內(nèi)核信號(hào)量設(shè)計(jì)與實(shí)現(xiàn)

    控制路徑可以睡眠。我們從 LINUX內(nèi)核信號(hào)量最直觀的設(shè)計(jì)/實(shí)現(xiàn)出發(fā),通過(guò)一步步改進(jìn),揭示在x86平臺(tái)上完整的信號(hào)量設(shè)計(jì)/實(shí)現(xiàn),然后探討在不同平臺(tái)上通用的
    發(fā)表于 01-14 16:55 ?18次下載

    LINUX內(nèi)核信號(hào)量設(shè)計(jì)與實(shí)現(xiàn)

    控制路徑可以睡眠。我們從 LINUX內(nèi)核信號(hào)量最直觀的設(shè)計(jì)/實(shí)現(xiàn)出發(fā),通過(guò)一步步改進(jìn),揭示在x86平臺(tái)上完整的信號(hào)量設(shè)計(jì)/實(shí)現(xiàn),然后探討在不同平臺(tái)上通用的
    發(fā)表于 01-14 16:55 ?5次下載

    Linux內(nèi)核GPIO操作函數(shù)的詳解分析

    本文檔的主要內(nèi)容詳細(xì)介紹的是Linux內(nèi)核GPIO操作函數(shù)的詳解分析免費(fèi)下載。
    發(fā)表于 01-22 16:58 ?28次下載

    linux內(nèi)核源代碼詳解

     在安裝好的Linux系統(tǒng)中,內(nèi)核的源代碼位于/ust/src/linux.如果是從GNU網(wǎng)站下載的Linux內(nèi)核的tar文件,則展開以后在
    發(fā)表于 09-06 17:01 ?4次下載