首頁 系統教程 Linux linux異步訊號handle淺析

linux異步訊號handle淺析

Feb 13, 2024 pm 10:03 PM
linux linux教程 linux系統 linux指令 shell腳本 嵌入式linux linux入門 linux學習

Linux系統是一種支援多任務並發執行的作業系統,它可以同時運行多個進程,從而提高系統的使用率和效率。但是,如果這些進程之間需要進行資料交換和協作,就需要使用一些進程間通訊(IPC)的方式,例如訊息佇列、共享記憶體、信號量等。其中,訊號是一種比較簡單而靈活的IPC方式,它可以讓一個行程向另一個行程發送簡短的訊息,通知它發生了某種事件或異常。 Linux系統中的訊號有兩種類型,分別是同步訊號和非同步訊號。本文將淺析linux非同步訊號handle的方法,包括非同步訊號的意義、產生、發送、接收、處理和忽略等面向。

linux異步訊號handle淺析

#在初學linux程式設計的時候,一直覺得非同步訊號handle是個很神奇的東西,使用者程式可以使用singal之類的系統呼叫為某某訊號註冊一個訊號處理函數(handle函數)。
程式的二進位程式碼在記憶體中都有確定的執行流程,為什麼收到非同步訊號以後,程式會被“中斷”,然後跳到這個handle函數裡面去運作呢?核心怎麼有能力讓程式做這樣的跳轉呢,總不可能臨時修改程式的可執行程式碼吧?

後來學習了一些核心知識,才知道原來行程收到訊號以後,並不是立即就被「中斷」的,而是先在行程的控制結構(task_struct)中記錄下收到了某某訊號,然後等到行程即將從內核態返回用戶態的時候,流程才被“中斷”,handle函數才會被呼叫。
使用者行程什麼時候會從核心態返回使用者態呢?一般主要是三種情況:系統呼叫(使用者程序主動進入核心)、中斷(使用者程序被動進入核心)、被調度執行(使用者程序從等待執行變成正在執行)。
行程從收到訊號到它從核心態傳回用戶態的過程,是需要一定時間的。但是這個時間一般會很短,至少時鐘中斷會以較大的頻率(例如1毫秒一次)將使用者程序帶入核心(當然,只針對正在執行的進程)。

在進程即將從內核態傳回用戶態時,如果有訊號需要處理,對應的handle函數將被呼叫(當然,可能沒有註冊handle,這時內核對訊號進行預設的處理)。注意,現在的行程還在內核態,內核是怎麼呼叫用戶態的handle函數?
直接調用可以嗎?當然不行。核心程式碼運行在高CPU特權等級下,如果直接呼叫handle函數,則handle函數也會在相同的CPU特權下執行。那麼用戶將可以在handle函數裡面為所欲為。
所以,呼叫handle必須先回傳用戶態。但返回用戶態後,程式流程又不受核心控制了,難不成核心還真的把用戶進程的可執行程式碼暫時改掉?

內核實際的做法還是比較巧妙。使用者進程進入核心以後,都會在其對應的核心堆疊上留下返回位址,以便流程返回。核心呼叫handle函數的方法就是暫時改掉堆疊上的回傳位址,然後再按原有的回傳用戶態的流程去回傳。結果這一返回,就到了handle函數去了。 (當然,需要修改的不只回傳位址,而是一整個呼叫堆疊。)
雖然現在臨時把回傳地址改了,但使用者進程最終還是要回到原來那個回傳地址去的。那麼,原先的返回位址及其呼叫堆疊應該保存在哪裡呢?進程的內核堆疊空間有限,而且還需要應付handle函數中可能發生的系統調用,所以內核把這些資訊放在內核棧上是不現實的,只能壓到了用戶棧上去。

當handle函數執行完畢,執行流程要回到核心去。同樣,由於CPU特權等級不同,從handle函數返回核心時不能單純利用RET指令去返回的。需要執行一次系統呼叫。

在handle執行完後,為什麼要回到內核,再從內核回到原始回傳位址?如果直接回到原始的回傳地址那自然是很便捷。而且要這麼做也不難,原始回傳位址及其呼叫棧已經被壓到了用戶棧上,核心只需要在handle函數的呼叫棧上稍做手腳就行了。
1.返回到原始返回地址並不是回到那個地址就行了,需要把整個現場都恢復(主要是寄存器什麼的)。當然,核心也可以在使用者堆疊上面壓一些程式碼,來完成這些事情;
2、現在可能不只一個訊號要處理,最好讓使用者行程返回內核,繼續處理其他訊號;

為了傳回內核,首先,內核在回到handle函數之前,先將某個回傳位址壓到使用者堆疊上,以便從handle回傳時能夠回到指定的位址上。這個指定的位址其實也在行程的使用者堆疊上,核心又在這個位址上放了幾條指令(在堆疊上放置可執行程式碼),讓行程去呼叫一個名叫sigreturn的系統呼叫。

回到handle函數前的使用者堆疊大致如下:
原有資料 -> 呼叫sigreturn的指令(設其位址為a) -> 原始回傳位址及其呼叫堆疊 -> 傳回位址(值為a) -> handle的堆疊變數

核心在handle函數的呼叫堆疊上放置sigreturn指令,這是在linux 2.4時的做法。每次呼叫使用者的handle函數都需要向使用者堆疊拷貝這麼幾條指令,這並不太好。
linux 2.6有一個叫vsyscall page的頁面,上麵包含了核心為使用者程式準備的一些指令,其中就包含呼叫sigreturn指令。這個vsyscall頁被對應到每個行程的虛擬位址空間靠近末端的部分,被所有使用者行程共享,對於使用者行程是唯讀的。這樣,handle函數的呼叫堆疊上就不需要再塞入sigreturn指令了,直接將handle函數的回傳位址設為vsyscall頁中對應的程式碼即可。

為了讓handle執行完以後自動呼叫sigreturn返回內核,內核做了很多事情。那可不可以約定好,讓用戶自己去呼叫sigreturn呢?
當然,這是可以的。只是為了讓訊號處理機製成為一套完整的機制,核心並沒有這麼做。否則用戶在handle函數裡面忘記呼叫sigreturn的話,可能莫名其妙地進程就崩潰了。而編譯器也很難找出這樣的錯誤。

進程呼叫sigreturn系統呼叫重新進入核心後,壓在使用者堆疊上的原始返回位址及其呼叫堆疊被取得。最終核心又會修改棧,讓行程返回用戶空間時回到這個原始回傳位址。

本文淺析了linux非同步訊號handle的方法,包括非同步訊號的意義、產生、發送、接收、處理和忽略等面向。透過了解和掌握這些知識,我們可以掌握Linux訊號處理的核心知識,從而提高系統的穩定性和效率。當然,linux非同步訊號handle還有很多其他的特性和用法,需要我們不斷地學習和研究。希望本文能帶給你一些啟發和幫助。

以上是linux異步訊號handle淺析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

Linux的主要目的是什麼? Linux的主要目的是什麼? Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

vscode終端命令不能用 vscode終端命令不能用 Apr 15, 2025 pm 10:03 PM

VS Code 終端命令無法使用的原因及解決辦法:未安裝必要的工具(Windows:WSL;macOS:Xcode 命令行工具)路徑配置錯誤(添加可執行文件到 PATH 環境變量中)權限問題(以管理員身份運行 VS Code)防火牆或代理限制(檢查設置,解除限制)終端設置不正確(啟用使用外部終端)VS Code 安裝損壞(重新安裝或更新)終端配置不兼容(嘗試不同的終端類型或命令)特定環境變量缺失(設置必要的環境變量)

See all articles