Linux 2 4 核心學習筆記 訊號

2021-04-13 11:22:54 字數 2674 閱讀 1875

版權申明

0-31 這 32 個訊號稱為標準訊號。

從 32 到 63 之間的 32 個訊號稱為實時訊號。

可以通過 man 7 signal 檢視對「標準訊號」和「實時訊號」詳細的描述。

每個程序擁有乙個訊號等待佇列。在 task_struct 中有乙個 struct sigpending pending 域, 就是程序的訊號等待佇列。

當向乙個程序傳送訊號時,訊號會先被送入程序的訊號等待佇列,然後等到程序被排程到去處理訊號的時候,會從訊號等待佇列中依次取出訊號進行處理。

標準訊號不能排隊,而實時訊號可以排隊:

假設程序遮蔽了乙個標準訊號,當給它連續傳送多個相同的標準訊號,則只有第乙個被放入程序的訊號等待佇列中,後續的都被丟棄。

假設程序遮蔽了乙個實時訊號,當給它連續傳送多個相同的實時訊號,則所有的訊號都被放入程序的訊號接收佇列中。

實時訊號是在 posix.4 實時訊號擴充套件中定義的。

程序可以遮蔽它不想接收的訊號。

在 task_struct 中有乙個 block 域,指定了程序要遮蔽的訊號集合。

遮蔽訊號帶來的影響:

1、    當向乙個程序投遞訊號時,如果發現程序遮蔽了此訊號,則即使此程序處於睡眠狀態,也不喚醒它。(否則睡眠的程序會被喚醒)。

2、    當程序開始處理它的訊號等待佇列的時候,對於被遮蔽的訊號,不做處理。所以這些訊號會一直待在等待佇列中,直到程序解開對相應訊號的遮蔽,才能被處理。

但是 kill 和 term 這兩種訊號是不能遮蔽的。

使用者空間可以通過 kill()  或 sigqueue() 兩個系統呼叫來向乙個程序傳送訊號。

核心空間的入口是 sys_kill():

sys_kill()  ==>  kill_something_info()  ==>  kill_proc_info()  ==> send_sig_info()  ==>  deliver_signal() ==> send_signal()

1、    首先,根據 pid 找到對應的目標程序。 這是通過 find_task_by_pid() 實現的。

2、    如果目標程序對訊號的處理行為是「忽略」,則無需投遞

3、    對於標準訊號,如果前面已經有乙個相同訊號到達,程序還沒來得及處理,則不再投遞,訊號丟失。

4、    否則,訊號被掛在程序的訊號等待佇列中。

5、    如果程序遮蔽了此訊號,則不喚醒此程序

6、    否則,如果此程序處於 interupable 狀態,則喚醒此程序。

signal_wake_up() ==>  wake_up_process()

7、    如果程序處於其它狀態,則不做處理。

1、    從系統呼叫、中斷處理或者異常處理返回到使用者空間的前夕。這和程序排程是同乙個時機

在 arch/i386/kernel/entry.s 中,有如下彙編**:

entry(ret_from_sys_call)

cli                # need_resched and signals atomic test

cmpl $

0,need_resched(

%ebx)

jne reschedule

cmpl $

0,sigpending(

%ebx)

jne signal_return

可以看到,在返回到使用者空間前夕,會檢查 task_struct 中的 sigpending 域,如果非0,說明有訊號需要處理,轉而去處理訊號。

2、    給程序投遞完訊號後,如果發現程序處於睡眠(interupable)狀態,則喚醒此程序,而程序會檢查是否有訊號等待處理。

signal_wake_up()

}tbw

1、    在執行訊號處理程式的時候,是否要遮蔽此訊號?

在進入某個訊號處理 函式前,必須暫時遮蔽掉此訊號。

當handle_signal() 執行完以後,堆疊已經被更換,接下來就會進入使用者空間,執行訊號處理函式。

在handle_signal() 的最後,通過sigaddset(¤t->blocked,sig); 暫時遮蔽了對此訊號。

2、我們知道,當程序進入睡眠(可打斷)狀態,在此期間收到另乙個訊號,那麼,程序會被喚醒,執行新的訊號處理程式。

但是,如果程序處於執行狀態,且不執行任何系統呼叫,在此期間向它傳送訊號,則此程序不會立刻處理此訊號。那麼此程序什麼時候能檢查到有訊號要處理了?

答案是在時鐘中斷返回的時候!!!

前面說了,檢查訊號的時機是從系統呼叫、中斷或異常處理返回使用者空間的前夕,因此,時鐘中斷返回的時候,也是檢查訊號的時機。

由於時鐘中斷頻繁發生,因此訊號總會及時得到處理。

3、   在執行訊號處理程式期間,雖然不會再被相同的訊號打斷,但仍然可能被其它訊號打斷。

假設程序處理 a 訊號,那麼它首先需要把 a 訊號從訊號佇列中取出,然後再去執行相應的訊號處理函式,在執行過程中,如果又被另乙個訊號b打斷,則不會再去處理 a,因為 a 已經被從訊號佇列中取出了。同樣,必須先取下 b,然後再做處理,所以在此期間,如果又被 c 打斷,則不會再處理到 b 。當 c 處理完畢後,又返回到 b 中,處理完 b,又返回到 a。

假設有多個訊號在佇列上等待。

在一次排程時機中,程序檢查它的訊號等待佇列,對於處理方式為 sig_ign 和 sig_dfl 的訊號,不用返回到使用者空間。對於需要返回到使用者空間去執行訊號處理函式的情況,在一次排程時機中只處理乙個。

linux2 4核心 path walk流程簡析

這裡以path walk解析 usr lib glibc為例 int path walk const char name,struct nameidata nd while c c 計算每個分量的長度 this.len name const char this.name this.hash end ...

linux核心學習筆記

核心的配置 a.make s3c2410 deconfig b.make menuconfig 圖形化配置 c.使用廠家給出的配置 生成.config 編譯生成核心,使用如下命令 make vmlinux make uimage 帶頭部 真正核心 1 config 建立生成autoconf.h 供源...

Linux核心學習筆記

2.2 核心原始碼樹 arch 特定體系結構的原始碼 block crypto api crypto 核心原始碼文件 drivers 裝置驅動程式 firmware fs vfs和各種檔案系統 include 核心標頭檔案 init 核心引導和初始化 ipc 程序間通訊 kernel 像排程程式這樣...