【Linux探索學習】第二十七彈——信號(上):Linux 信號基礎詳解

Linux學習筆記:

https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482

前言:

前面我們已經將進程通信部分講完了,現在我們來講一個進程部分也非常重要的知識點——信號,信號也是進程間通信的一種,本篇主要講解信號的概念和信號的幾種產生方法及對應的場景

目錄

一、引言

二、信號的概念

2.1 什么是信號

2.2 信號的作用

2.3 信號的特點

2.4 常見信號列表

?編輯

三、信號的產生

3.1 前臺進程和后臺進程

3.2?用戶產生信號

3.3?系統產生信號

3.4?軟件產生信號

四、信號的處理

4.1 默認處理方式

4.2 自定義信號處理函數

五、總結


一、引言

在 Linux 操作系統中,信號(Signal)是一種進程間通信(IPC,Inter - Process Communication)的機制,它用于通知進程發生了某種異步事件。信號可以來自內核,也可以來自其他進程。進程接收到信號后,會根據信號的類型以及自身的處理方式做出相應的反應。理解信號對于編寫健壯的 Linux 程序以及深入理解 Linux 操作系統的運行機制至關重要。

二、信號的概念

2.1 什么是信號

信號是一種軟中斷,它是一種異步通知機制。當某個特定事件發生時,如用戶按下特定組合鍵、系統資源耗盡、進程異常終止等,系統會向相關進程發送一個信號。每個信號都有一個對應的編號和名稱,例如信號 1 表示 SIGHUP(掛起信號),信號 9 表示 SIGKILL(強制終止信號)。

2.2 信號的作用

信號的主要作用是讓進程能夠對異步事件做出響應。例如,當用戶在終端中按下 Ctrl + C 組合鍵時,系統會向當前前臺進程發送 SIGINT 信號,通常進程會接收到這個信號后停止當前正在執行的任務并退出。信號還可以用于進程間的通信,一個進程可以向另一個進程發送信號來通知其執行某些操作。

結合2.1和2.2我們來講解一個概念:信號是一種軟中斷,是什么意思呢?當我們往鍵盤中輸入內容時是如何告訴給內核的?ctrl+c又是如何被解釋為指令的呢?

我們先來看下面這張圖:

? ? ? ? 鍵盤實際上是通過中斷來讓操作系統知道自己要寫入內容的,鍵盤被按下時,就會觸發硬件中斷,不同的硬件對應著不同的中斷號,中斷單元就可以通過它們的中斷號將它們與CPU中不同的鍵位相連,從而使CPU中這個方向的寄存器(32位)特定位置產生電信號,操作系統中有一個叫中斷向量表的類似于函數指針結構體的結構,里面保存著訪問各種外設的方法,操作系統通過CPU產生的電信號就辨別出要獲取哪種硬件的信息,從而通過中斷向量表中的方法,將硬件中的信息拷貝到操作系統的文件緩沖區中(操作系統下一切皆文件,且每一個文件都有自己的文件緩沖中區),然后再拷貝到用戶緩沖區
? ? ? ?同時比如鍵盤等外鍵,操作系統在獲取鍵盤上的信息時會先進行識別,會對數據進行判斷,如果是控制進程的比如ctrl+c等組合鍵就不會往緩沖區中拷貝,我們可以發現我們學習的信號與上面的中斷過程很像,其實信號,就是用軟件方式,模擬的對講程的硬件中斷,所以信號也被叫做軟中斷

2.3 信號的特點

  1. 異步性:信號的產生是異步的,與進程的執行順序無關。進程在運行過程中可能隨時收到信號。
  1. 簡單性:信號機制相對簡單,只需要一個信號編號就可以標識不同的信號。
  1. 有限性:Linux 系統中定義的信號數量是有限的,不同的系統可能略有差異,但通常在幾十種左右。

2.4 常見信號列表

信號編號

信號名稱

含義

默認處理方式

1

SIGHUP

掛起信號,通常在終端關閉時發送給相關進程

終止進程

2

SIGINT

中斷信號,由用戶按下 Ctrl + C 組合鍵產生

終止進程

3

SIGQUIT

退出信號,由用戶按下 Ctrl + \ 組合鍵產生

終止進程并生成核心轉儲文件

9

SIGKILL

強制終止信號,不能被捕獲、阻塞或忽略

立即終止進程

15

SIGTERM

終止信號,通常用于正常終止進程

終止進程

18

SIGCONT

繼續信號,用于恢復被暫停的進程

繼續執行進程

19

SIGSTOP

停止信號,用于暫停進程,不能被捕獲、阻塞或忽略

暫停進程

可以通過kill -l指令查看所有信號

kill -l

三、信號的產生

3.1 前臺進程和后臺進程

先來科普一個小知識點:前臺進程和后臺進程,來看下面一個程序

#include<iostream>
#include<unistd.h>
using namespace std;
int main()
{while(true){cout<<"I am a crazy process"<<endl;sleep(1);}return 0;
}

我們進行編譯后會得到一個可執行程序

./myfile

我們這樣執行時我們會發現在程序運行的時候,我們輸入其它指令比如Is,pwd等都不會有結果,進程還在繼續運行,除非用ctrl+c終止掉進程,這樣的進程稱為前臺進程

./myfile &

這種的后面加上地址符的叫做后臺進程,后臺進程可以被其它進程命令臨時打斷并執行這個命令,比如我們輸入ls指令,進程就會暫停并且輸出Is的結果,但是最后需要自己把進程結束掉

Linux中,一次登陸中, 一個終端,一般會配上一個bash,每一個登陸,只允許一個進程是前臺進程,可以允許多個進程是后臺進程
當./process運行時,輸入指令之所以不能運行就是因為此時的前臺進程由bash轉變為了process

  • 終端占用情況
    • 前臺進程:會獨占終端,直到進程執行完成或者被掛起,在這期間終端無法接受其他命令輸入,用戶只能與該進程進行交互。
    • 后臺進程:不會占用終端,終端可以繼續接受用戶輸入的其他命令,用戶可以在同一個終端中同時啟動多個后臺進程,并隨時切換到其他任務。
  • 運行特性
    • 前臺進程:其執行過程會受到用戶操作的直接影響,比如用戶可以通過鍵盤輸入來中斷或暫停進程。如果終端關閉,前臺進程通常會被終止,除非進行了特殊的設置。
    • 后臺進程:通常是長時間運行的,不受終端關閉的影響,除非明確地對其進行停止或重啟操作。它按照自身的邏輯和任務需求在后臺持續運行,不會因為用戶的一些常規操作而中斷。

3.2?用戶產生信號

  1. 鍵盤輸入:用戶可以通過在終端中按下特定的組合鍵來產生信號。例如:
    • Ctrl + C:產生 SIGINT 信號,用于中斷當前正在運行的進程。比如,我們在終端中運行一個長時間運行的命令while true; do echo "Hello"; sleep 1; done,按下 Ctrl + C 后,該命令對應的進程會接收到 SIGINT 信號并終止。
    • Ctrl + \:產生 SIGQUIT 信號,不僅會終止進程,還會生成核心轉儲文件(如果系統配置允許,一般在云服務器上是默認關閉的,虛擬機上可能是開啟的)。例如,運行一個簡單的 C 程序#include <stdio.h> int main() { while(1); return 0; },編譯運行后,按下 Ctrl + \,進程會終止并生成核心轉儲文件(在當前目錄下,文件名為 core,具體名稱和位置可能因系統配置而異)。(了解即可,這個生成core文件的內容與進程退出部分也有聯系,有想了解的可以單獨去搜索一下)
  1. 使用 kill 命令:用戶可以使用 kill 命令向指定進程發送信號。kill 命令的基本語法是kill [信號編號] 進程ID。例如,要向進程 ID 為 1234 的進程發送 SIGTERM 信號(信號編號為 15),可以在終端中輸入kill -15 1234,也可以使用信號名稱kill -SIGTERM 1234。如果省略信號編號或名稱,默認發送 SIGTERM 信號。

3.3?系統產生信號

  1. 進程異常:當進程發生異常時,如段錯誤(訪問非法內存地址)、除零錯誤等,系統會向該進程發送相應的信號。
    • 段錯誤(Segmentation Fault):當進程訪問了不屬于它的內存區域時,會產生段錯誤,一般都是野指針問題,系統會向該進程發送 SIGSEGV 信號。例如,下面的 C 代碼會導致段錯誤:
#include <stdio.h>int main() {int *ptr = NULL;*ptr = 10; // 試圖向空指針指向的地址寫入數據,會引發段錯誤return 0;}

編譯運行這段代碼,程序會崩潰,并提示 “Segmentation fault”,這是因為進程接收到了 SIGSEGV 信號。

  • 除零錯誤(Division by Zero):當進程執行除法運算時,如果除數為零,會產生除零錯誤,系統會向該進程發送 SIGFPE 信號。例如:
#include <stdio.h>int main()
{int a = 10;int b = 0;int c = a / b; // 除零操作,會引發除零錯誤return 0;
}

運行這段代碼,程序會崩潰,并提示 “Floating point exception”,這是因為進程接收到了 SIGFPE 信號。

2. 系統資源相關:當系統資源達到一定閾值時,也可能產生信號。例如,當進程使用的內存超過了系統限制時,系統可能會發送 SIGKILL 信號來終止該進程,以防止系統內存耗盡。不過,這種情況通常需要系統進行相關的配置和監控。

3.4?軟件產生信號

  1. 使用 kill 函數:在 C 語言編程中,可以使用 kill 函數向指定進程發送信號。kill 函數的原型可以用man手冊查看,如下:
 man 2 kill

其中,pid 是目標進程的 ID,sig 是要發送的信號編號。例如,下面的代碼演示了如何使用 kill 函數向另一個進程發送 SIGTERM 信號:

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main()
{pid_t target_pid = 1234; // 假設目標進程ID為1234int result = kill(target_pid, SIGTERM);if (result == -1){perror("kill failed");}else{printf("SIGTERM sent to process %d\n", target_pid);}return 0;
}

在實際使用中,需要將target_pid替換為真實的目標進程 ID。

2. 使用 raise 函數:進程可以使用 raise 函數向自身發送信號。raise 函數的原型也可以通過man手冊來查看,如下:

man raise

其中,sig 是要發送的信號編號。例如,下面的代碼演示了如何使用 raise 函數向自身發送 SIGINT 信號:

#include <stdio.h>
#include <signal.h>
int main()
{int result = raise(SIGINT);if (result != 0){perror("raise failed");}else{printf("SIGINT sent to self\n");}return 0;
}

運行這段代碼,進程會接收到自己發送的 SIGINT 信號并終止。

四、信號的處理

4.1 默認處理方式

每個信號都有一個默認的處理方式,常見的默認處理方式包括:

  1. 終止進程:如 SIGINT、SIGTERM 等信號的默認處理方式是終止進程。
  1. 生成核心轉儲文件并終止進程:例如 SIGQUIT 信號,在終止進程的同時會生成核心轉儲文件,該文件包含了進程在收到信號時的內存狀態等信息,可用于調試程序。
  1. 忽略信號:有些信號(如 SIGCHLD,子進程狀態改變時發送給父進程的信號)的默認處理方式是忽略。

4.2 自定義信號處理函數

進程可以通過調用 signal 函數或 sigaction 函數來設置自定義的信號處理函數。

  1. signal 函數:signal 函數的原型如下:
man signal

其中,signum 是信號編號,handler 是指向信號處理函數的指針。例如,下面的代碼演示了如何使用 signal 函數設置 SIGINT 信號的自定義處理函數:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signal_handler(int signum)
{printf("Received SIGINT. Cleaning up...\n");// 在這里進行一些清理工作,如關閉文件、釋放資源等_exit(0); // 退出進程
}
int main()
{signal(SIGINT, signal_handler);while (1){printf("Running...\n");sleep(1);}return 0;
}

在這個例子中,當進程接收到 SIGINT 信號時,會調用signal_handler函數,而不是默認的終止進程操作。

2. sigaction 函數:sigaction 函數比 signal 函數提供了更豐富的功能,它可以設置信號處理函數、處理信號時的掩碼、信號的標志等。sigaction 函數的原型如下:

#include <signal.h>int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);struct sigaction {void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;int sa_flags;void (*sa_restorer)(void);};

其中,signum 是信號編號,act 是指向新的信號處理動作的結構體指針,oldact 是指向舊的信號處理動作的結構體指針(如果不需要獲取舊的處理動作,可以設為 NULL)。例如,下面的代碼演示了如何使用 sigaction 函數設置 SIGINT 信號的自定義處理函數:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signal_handler(int signum)
{printf("Received SIGINT. Cleaning up...\n");// 在這里進行一些清理工作,如關閉文件、釋放資源等_exit(0); // 退出進程
}
int main()
{struct sigaction new_action, old_action;new_action.sa_handler = signal_handler;sigemptyset(&new_action.sa_mask);new_action.sa_flags = 0;sigaction(SIGINT, &new_action, &old_action);while (1){printf("Running...\n");sleep(1);}return 0;
}

這段代碼與使用 signal 函數的例子功能類似,但使用 sigaction 函數可以更靈活地配置信號處理方式。

五、總結

信號是 Linux 系統中一種重要的進程間通信和異步事件通知機制。通過本文,我們詳細了解了信號的概念,信號的產生和部分信號的處理工作,后面我們還會講解信號的捕捉等處理工作,學習信號可以幫助我們更好的實現進程通信和異步處理等諸多操作

本篇筆記:


感謝各位大佬觀看,創作不易,還請各位大佬點贊支持!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70243.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70243.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70243.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nginx負載均衡, 解決iphash不均衡的問題之consistent

原因分析 客戶端IP分布不均&#xff1a;部分IP段請求集中&#xff0c;導致哈希到同一后端。 服務器數量變動&#xff1a;增刪節點時&#xff0c;傳統ip_hash未使用一致性哈希&#xff0c;導致分布重置。 哈希鍵范圍過小&#xff1a;例如僅使用IPv4前24位&#xff0c;不同IP可…

[C++]多態詳解

目錄 一、多態的概念 二、靜態的多態 三、動態的多態 3.1多態的定義 3.2虛函數 四、虛函數的重寫&#xff08;覆蓋&#xff09; 4.1虛函數 4.2三同 4.3兩種特殊情況 &#xff08;1&#xff09;協變 &#xff08;2&#xff09;析構函數的重寫 五、C11中的final和over…

WEB安全--SQL注入--PDO與繞過

一、PDO介紹&#xff1a; 1.1、原理&#xff1a; PDO支持使用預處理語句&#xff08;Prepared Statements&#xff09;&#xff0c;這可以有效防止SQL注入攻擊。預處理語句將SQL語句與數據分開處理&#xff0c;使得用戶輸入的數據始終作為參數傳遞給數據庫&#xff0c;而不會直…

ES12 weakRefs的用法和使用場景

ES12 (ECMAScript 2021) 特性總結&#xff1a;WeakRef 1. WeakRef 概述 描述 WeakRef 是 ES12 引入的一個新特性&#xff0c;用于創建對對象的弱引用。弱引用不會阻止垃圾回收器回收對象&#xff0c;即使該對象仍然被弱引用持有。WeakRef 通常與 FinalizationRegistry 結合使…

50頁精品PPT | 某大數據資產平臺建設項目啟動會材料

該PPT主要介紹了某集團大數據資產平臺建設項目的啟動會材料&#xff0c;圍繞數據作為數字經濟時代核心生產要素的背景&#xff0c;結合國家戰略和集團數字化轉型需求&#xff0c;分析了當前數據資源整合不足、孤島現象嚴重、質量管控薄弱及共享機制不完善等問題&#xff0c;提出…

8.【線性代數】——求解Ax=b

八 求解Axb 1. 解Axb求特解 x p x_p xp?求特解 x n x_n xn?所有解 2. Axb什么時候有解3. A m ? n A_{m * n} Am?n?不同秩的Axb解分析3.1 列滿秩 rn<m3.2 行滿秩 rm<n3.3 rmn3.4 r<m 且 r < n3.5 綜述 1. 解Axb 求解 { x 1 2 x 2 2 x 3 2 x 4 b 1 2 x 1…

動靜態鏈接與加載

目錄 靜態鏈接 ELF加載與進程地址空間&#xff08;靜態鏈接&#xff09; 動態鏈接與動態庫加載 GOT表 靜態鏈接 對于多個.o文件在沒有鏈接之前互相是不知到對方存在的&#xff0c;也就是說這個.o文件中調用函數的的跳轉地址都會被設定為0&#xff08;當然這個函數是在其他.…

Web 后端 請求與響應

一 請求響應 1. 請求&#xff08;Request&#xff09; 客戶端向服務器發送的HTTP請求&#xff0c;通常包含以下內容&#xff1a; 請求行&#xff1a;HTTP方法&#xff08;GET/POST等&#xff09;、請求的URL、協議版本。 請求頭&#xff08;Headers&#xff09;&#xff1a;…

【Excel筆記_6】條件格式和自定義格式設置表中數值超過100保留1位,超過1000保留0位,低于100為默認

方法一&#xff1a;自定義格式 選中需要設置格式的單元格區域。右鍵選擇設置單元格格式&#xff0c;或者在工具欄中選擇開始 -> 數字 -> 自定義格式。在類型框中輸入以下自定義格式&#xff1a; [>1000]0;[>100]0.0;G/通用格式解釋&#xff1a; [>1000]0&…

排序與算法:希爾排序

執行效果 希爾排序的執行效果是這樣的&#xff1a; 呃……看不懂嗎&#xff1f;沒關系&#xff0c;接著往下看介紹 算法介紹 希爾排序算法&#xff08;Shell Sort&#xff09;是按其設計者希爾&#xff08;Donald Shell&#xff09;的名字命名&#xff0c;該算法由 1959 年公布…

Python HTTP 請求工具類 HttpUtils:簡化 HTTP 請求的高效工具

在現代的 Web 開發和 API 集成中,HTTP 請求是最常見的操作之一。無論是獲取數據、提交表單,還是與 RESTful API 交互,我們都需要頻繁地發送 HTTP 請求。為了簡化這些操作,提升代碼的可讀性和可維護性,我們可以使用一個高效的工具類——HttpUtils。本文將詳細介紹 HttpUtil…

親測Windows部署Ollama+WebUI可視化

一. Ollama下載 登錄Ollama官網(Ollama)點擊Download進行下載 如果下載很慢可用以下地址下載&#xff1a; https://github.com/ollama/ollama/releases/download/v0.5.7/OllamaSetup.exe 在DeepSeek官網上&#xff0c;你可以直接點擊【model】 到達這個界面之后&#xff0c;…

用xml配置spring, bean標簽有哪些屬性?

用xml配置spring, bean標簽有哪些屬性? 在Spring框架中&#xff0c;使用XML配置文件時&#xff0c;<bean>標簽用于定義一個Bean。以下是一些常用的<bean>標簽屬性&#xff1a; 1. class 描述&#xff1a;指定Bean的類名。示例&#xff1a;<bean id"myBe…

50頁PDF|數字化轉型成熟度模型與評估(附下載)

一、前言 這份報告依據GBT 43439-2023標準&#xff0c;詳細介紹了數字化轉型的成熟度模型和評估方法。報告將成熟度分為五個等級&#xff0c;從一級的基礎轉型意識&#xff0c;到五級的基于數據的生態價值構建與創新&#xff0c;涵蓋了組織、技術、數據、資源、數字化運營等多…

golang panic信息捕獲

背景 我們的日志接入阿里云sls平臺&#xff0c;但是&#xff0c;日志是以json的格式存儲在阿里云sls平臺上&#xff0c;程序中產生的error,info等日志都可以實現以json的格式打印。但是&#xff0c;golang程序中產生的panic信息本身不是以json的格式輸出&#xff0c;這就導致p…

攔截器VS過濾器:Spring Boot中請求處理的藝術!

目錄 一、攔截器&#xff08;Interceptor&#xff09;和過濾器&#xff08;Filter&#xff09;&#xff1a;都是“守門員”&#xff01;二、如何實現攔截器和過濾器&#xff1f;三、攔截器和過濾器的區別四、執行順序五、真實的應用場景六、總結 &#x1f31f;如果喜歡作者的講…

FastGPT及大模型API(Docker)私有化部署指南

??歡迎關注【AI技術開發者】 ? 經過優化&#xff0c;在不影響FastGPT功能的情況下&#xff0c;大幅降低了部署的設備配置要求&#xff0c;僅需1c1h即可正常部署使用。 官方要求配置&#xff1a; ? ? 優化后的實際占用情況&#xff1a; 運行內存僅需370M&#xff08…

解決 WSL Ubuntu 中 /etc/resolv.conf 自動重置問題

解決 WSL Ubuntu 中 /etc/resolv.conf 自動重置問題 前言問題描述問題原因嘗試過的命令及分析解決方案&#xff1a;修改 wsl.conf 禁用自動生成總結 前言 在使用 Windows Subsystem for Linux (WSL) 的 Ubuntu 子系統時&#xff0c;你可能會遇到 /etc/resolv.conf 文件被自動重…

【第15章:量子深度學習與未來趨勢—15.3 量子深度學習在圖像處理、自然語言處理等領域的應用潛力分析】

一、開篇:為什么我們需要關注這場"量子+AI"的世紀聯姻? 各位技術愛好者們,今天我們要聊的這個話題,可能是未來十年最值得押注的技術革命——量子深度學習。這不是簡單的"1+1=2"的物理疊加,而是一場可能徹底改寫AI發展軌跡的范式轉移。 想象這樣一個…

企業軟件合規性管理:構建高效、安全的軟件資產生態

引言 在數字化轉型的浪潮下&#xff0c;企業的軟件使用方式日益多元化&#xff0c;涉及云端、訂閱制、永久授權及浮動許可等多種模式。然而&#xff0c;隨著軟件資產的增多&#xff0c;企業面臨著合規性管理的嚴峻挑戰&#xff1a;非法軟件使用、許可證管理不當、軟件資產閑置…