Linux進程信號(三)之信號產生2

文章目錄

      • 4. 由軟件條件產生信號
      • 5. 硬件異常產生信號
        • 模擬一下除0錯誤和野指針異常
          • 除0錯誤
          • 野指針錯誤
      • 總結思考一下

4. 由軟件條件產生信號

SIGPIPE是一種由軟件條件產生的信號,在“管道”中已經介紹過了。

image-20250421161453471

軟件條件不就緒,很明顯這個軟件條件沒有直接報錯,而是通過返回值來反映。

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;int main()
{char buffer[1024];int n=1024;n=read(4,buffer,sizeof(buffer));printf("n=%d\n",n);perror("read");return 0;
}

image-20250421162729359

軟件條件可能會產生信號也可能不會,取決于操作系統本身。

操作系統是由對軟件檢測的能力的,所以能通過軟件條件產生信號。

本節主要介紹alarm函數 和SIGALRM信號。

image-20250421163823918

image-20250421164025016

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
調用alarm函數可以設定一個鬧鐘,
也就是告訴內核在seconds秒之后給當前進程發SIGALRM信號, 
該信號的默認處理動作是終止當前進程。

這個函數的返回值是0或者是以前設定的鬧鐘時間還余下的秒數。

打個比方:

某人要小睡一覺,設定鬧鐘為30分鐘之后響,

20分鐘后被人吵醒了,還想多睡一會兒,

于是重新設定鬧鐘為15分鐘之后響,“以前設定的鬧鐘時間還余下的時間”就是10分鐘。

如果seconds值為0,表示取消以前設定的鬧鐘,

函數的返回值仍然是以前設定的鬧鐘時間還余下的秒數

例 alarm

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;
int main()
{alarm(5);while(1){cout<<"proc is running"<<endl;sleep(1);}return 0;
}

image-20250421164457780

驗證:收到了14號信號

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;
}int main()
{signal(14,handler);alarm(5);while(1){cout<<"proc is running"<<endl;sleep(1);}return 0;
}

image-20250421164824619

因為只設置一次,鬧鐘只響了一次(因為不是異常)

如果想讓鬧鐘每隔5秒響一次

(收到了14號信號,就去調用處理方法,

在調用方法里,又設置了一個鬧鐘,5秒之后,又收到了14號信號,繼續調用處理方法……)

void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;alarm(5);
}

image-20250421165141207

查看剩余時間

收到了14號信號,那么調用處理方法,鬧鐘將會重新設置,alarm(5)

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;int n=alarm(5);cout<<"time: "<<n<<endl;
}int main()
{signal(14,handler);int n=alarm(50);while(1){cout<<"proc is running,pid: "<<getpid()<<endl;sleep(1);}return 0;
}

image-20250421170457161

操作系統內部會有很多鬧鐘,所以OS要管理鬧鐘,

先描述再組織,對鬧鐘的管理就變成了對鏈表的增刪查改。

鬧鐘的描述:有指向進程的指針,有時間(使用時間戳)

時間戳+設定的時間=未來時間

如果現在時間大于等于這個未來時間就表示超時了。

遍歷鏈表對比時間,如果時間到了就發送信號,該節點就可以從鏈表里刪除了。

提高效率:

使用優先級隊列或者堆等數據結構。

最小堆,將數據結構都放進最小堆,

堆頂數據沒有超時,那么整個堆都沒有超時。

堆頂超時了,只要將堆頂處理,就可以移除堆頂元素。

5. 硬件異常產生信號

硬件異常被硬件以某種方式被硬件檢測到并通知內核,

然后內核向當前進程發送適當的信號。

例如當前進程執行了除以0的指令,

CPU的運算單元會產生異常,

內核將這個異常解釋 為SIGFPE信號發送給進程。

再比如當前進程訪問了非法內存地址,

MMU會產生異常,內核將這個異常解釋為SIGSEGV信號發送給進程。

捕捉信號,不是為了解決出現的問題,

而是為了讓用戶知道進程為什么掛了。(做做收尾工作)

模擬一下除0錯誤和野指針異常

makefile

mysignal:mysignal.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -rf mysignal
除0錯誤

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;int main()
{cout<<"div before"<<endl;sleep(1);int a=10;a/=0;cout<<"div after"<<endl;sleep(1);return 0;
}

image-20250420223834069

證明收到了8號信號

image-20250420224125165

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;//只是打印了一行信息,其他什么都沒干
}int main()
{signal(8,handler);cout<<"div before"<<endl;// sleep(1);int a=10;a/=0;cout<<"div after"<<endl;// sleep(1);return 0;
}

image-20250420225220573

代碼為什么一直都不退出呢?

因為8號信號的默認動作是退出,但是現在改成了自定義動作,

自定義動作只有打印信息沒有設置退出,所以進程不會退出。

野指針錯誤

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;int main()
{cout<<"point error before"<<endl;int *p=nullptr;//p指向0號地址*p=100;//沒有資格訪問0號地址(權限問題/野指針問題)cout<<"point error after"<<endl;return 0;
}

image-20250420230117465

驗證收到11號信號

image-20250420230550597

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;//只是打印了一行信息,其他什么都沒干
}int main()
{signal(11,handler);cout<<"point error before"<<endl;int *p=nullptr;//p指向0號地址*p=100;//沒有資格訪問0號地址(權限問題/野指針問題)cout<<"point error after"<<endl;return 0;
}

image-20250420230416654

以上證明,進程出了異常不一定會退出,只要捕捉信號即可。

(但是不退出意義不大了,還占用著CPU的資源)

不退出就會一直被調度運行,硬件異常沒有被修正,

然后運行又有硬件報錯,然后OS一直發信號,

進程收到信號繼續被捕捉……如此循環。

由此可以確認,我們在C/C++當中除零,內存越界等異常,

在系統層面上,是被當成信號處理的。


為什么除0和野指針會讓進程崩潰呢?

因為收到了信號,該信號的默認處理動作是終止進程自己。

為什么除0和野指針會給進程發信號呢?

因為硬件發生了報錯,OS檢測到了,所以給進程發信號。

OS怎么知道發生了除0和野指針?

除0:

image-20250421102446425

所以,除0錯誤最終會被轉化成硬件問題,

OS識別到了硬件報錯,

所以OS要給進程發信號,

所以進程收到信號會自己終止(崩潰)。

野指針:

image-20250421105356726

CPU內部不同的寄存器的報錯代表不同的信號。

總結思考一下

上面所說的所有信號產生,最終都要有OS來進行執行,為什么?

因為OS是進程的管理者!

OS是進程的管理者信號的處理是否是立即處理的?

不是立即處理。進程可能正在做更重要的事。

在合適的時候,信號如果不是被立即處理,那么信號是否需要暫時被進程記錄下來?記錄在哪里最合適呢?

一個進程在沒有收到信號的時候,能否能知道,自己應該對合法信號作何處理呢?

如何理解OS向進程發送信號?能否描述一下完整的發送處理過程?

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

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

相關文章

讀取18B20的問題,時鐘太慢了

使用MSP430&#xff0c;1M時鐘&#xff0c;在讀取18B20數據時&#xff0c;一直存在問題&#xff0c;使用邏輯分析儀讀取的數據也是莫名其妙&#xff0c;查看電路圖和器件也沒有發現問題&#xff0c;就這樣斷斷續續的卡了一周多。 今天忽然想把時鐘升一下試試&#xff0c;原來1…

第12章 Java多線程機制

12.1 進程與線程 4種狀態&#xff1a;新建、運行、中斷和死亡。 &#xff08;新建、運行、中斷和死亡&#xff09; 建立線程的兩種方法&#xff1a;用Thread類或其子類。 線程新建后&#xff0c;必須調用 start () 方法使其進入就緒隊列&#xff0c;才有機會獲得 CPU 資源&a…

利用 Amazon Bedrock Data Automation(BDA)對視頻數據進行自動化處理與檢索

當前點播視頻平臺搜索功能主要是基于視頻標題的關鍵字檢索。對于點播平臺而言&#xff0c;我們希望可以通過優化視頻搜索體驗滿足用戶通過模糊描述查找視頻的需求&#xff0c;從而提高用戶的搜索體驗。借助 Amazon Bedrock Data Automation&#xff08;BDA&#xff09;技術&…

React 19版本refs也支持清理函數了。

文章目錄 前言一、refs 支持清理函數二、案例演示1.useEffect寫法2.React 19改進 的ref寫法 總結 前言 React 19版本發布了ref支持清理函數了&#xff0c;這樣就可以達到useEffect一樣的效果了。為啥需要清理函數呢&#xff0c;這是因為節約內存。 清理事件監聽&#xff08;避…

城市內澇監測預警系統守護城市安全

一、系統背景 城市內澇是指由于強降水或連續性降水超過城市排水能力&#xff0c;導致城市內產生積水災害的現象。隨著氣候變化和城市化進程的加快&#xff0c;城市內澇現象愈發頻繁和嚴重。傳統的城市排水系統已難以滿足當前的城市排水需求&#xff0c;特別是在暴雨等極端天氣條…

Flink 作業提交流程

Apache Flink 的 作業提交流程&#xff08;Job Submission Process&#xff09; 是指從用戶編寫完 Flink 應用程序&#xff0c;到最終在 Flink 集群上運行并執行任務的整個過程。它涉及多個組件之間的交互&#xff0c;包括客戶端、JobManager、TaskManager 和 ResourceManager。…

ctr查看鏡像

# 拉取鏡像到 k8s.io 命名空間 sudo nerdctl --namespace k8s.io pull nginx:1.23.4 # 驗證鏡像是否已下載 sudo nerdctl --namespace k8s.io images 下載鏡像到k8s.io名稱空間下 nerdctl --namespace k8s.io pull zookeeper:3.6.2 sudo ctr image pull --namespace k8s.io …

中科院自動化研究所通用空中任務無人機!基于大模型的通用任務執行與自主飛行

作者&#xff1a; Ji Zhao and Xiao Lin 單位&#xff1a;中科院自動化研究所 論文標題&#xff1a;General-Purpose Aerial Intelligent Agents Empowered by Large Language Models 論文鏈接&#xff1a;https://arxiv.org/pdf/2503.08302 主要貢獻 硬件-軟件協同設計框…

數據結構 -- 樹形查找(三)紅黑樹

紅黑樹 為什么要發明紅黑樹 平衡二叉樹AVL&#xff1a;插入/刪除很容易破壞平衡性&#xff0c;需要頻繁調整樹的形態。如&#xff1a;插入操作導致不平衡&#xff0c;則需要先計算平衡因子&#xff0c;找到最小不平衡子樹&#xff08;時間開銷大&#xff09;&#xff0c;在進行…

容器化-k8s-使用和部署

一、K8s 使用 1、基本概念 集群: 由 master 節點和多個 slaver 節點組成,是 K8s 的運行基礎。節點: 可以是物理機或虛擬機,是 K8s 集群的工作單元,運行容器化應用。Pod: K8s 中最小的部署單元,一個 Pod 可以包含一個或多個緊密相關的容器,這些容器共享網絡和存儲資源。…

力扣-283-移動零

1.題目描述 2.題目鏈接 283. 移動零 - 力扣&#xff08;LeetCode&#xff09; 3.題目代碼 class Solution {public void moveZeroes(int[] nums) {int dest-1;int cur0;while(cur<nums.length){if(nums[cur]0){cur;}else if(nums[cur]!0){swap(nums,cur,dest1);cur;dest…

前端開發筆記與實踐

一、Vue 開發規范與響應式機制 1. 組件命名規范 自定義組件使用大駝峰命名法&#xff08;如 MyComponent&#xff09;&#xff0c;符合 Vue 官方推薦&#xff0c;便于與原生 HTML 元素區分。 2. Proxy vs defineProperty 特性Proxy&#xff08;Vue3&#xff09;Object.defi…

如何給PSCAD添加庫文件

1、點擊Options 2、選擇藍色的選項 3、查看Intel(R) Visual Fortran Compiler XE 的版本 4、打開原文件的Library 5、打開 6、點擊這個文件的右鍵 7、然后選擇第一項project setting 9、先把第8步中link里面原有的路徑刪除&#xff0c;再點browes[A1] &#xff0c;然后選擇 [A…

milvus+flask山寨《從零構建向量數據庫》第7章case2

繼續流水賬完這本書&#xff0c;這個案例是打造文字形式的個人知識庫雛形。 create_context_db: # Milvus Setup Arguments COLLECTION_NAME text_content_search DIMENSION 2048 MILVUS_HOST "localhost" MILVUS_PORT "19530"# Inference Arguments…

【第一篇】 創建SpringBoot工程的四種方式

簡介&#xff1a; 通過此篇博客你可以使用任何方式進行創建 SpringBoot 項目&#xff0c;并且在文章的最后附上答疑解惑一節&#xff0c;為你排除在使用過程中發生的常見問題。文章內容若存在錯誤或需改進的地方&#xff0c;歡迎大家指正&#xff01;若對操作有任何疑問歡迎留言…

GPT( Generative Pre-trained Transformer )模型:基于Transformer

GPT是由openAI開發的一款基于Transformer架構的預訓練語言模型&#xff0c;擁有強大的生成能力和多任務處理能力&#xff0c;推動了自然語言處理&#xff08;NLP&#xff09;的快速發展。 一 GPT發展歷程 1.1 GPT-1&#xff08;2018年&#xff09; 是首個基于Transformer架構…

網絡檢測工具InternetTest v8.9.1.2504 單文件版,支持一鍵查詢IP/DNS、WIFI密碼信息

—————【下 載 地 址】——————— 【?本章下載一】&#xff1a;https://drive.uc.cn/s/295e068b79314 【?本章下載二】&#xff1a;https://pan.xunlei.com/s/VOQDXguH0DYPxrql5y2zlkhTA1?pwdg2nx# 【百款黑科技】&#xff1a;https://ucnygalh6wle.feishu.cn/wiki/…

CSS- 4.1 浮動(Float)

本系列可作為前端學習系列的筆記&#xff0c;代碼的運行環境是在HBuilder中&#xff0c;小編會將代碼復制下來&#xff0c;大家復制下來就可以練習了&#xff0c;方便大家學習。 HTML系列文章 已經收錄在前端專欄&#xff0c;有需要的寶寶們可以點擊前端專欄查看&#xff01; 點…

配置WebStorm鍵盤快捷鍵

目錄 配置快捷鍵添加鍵盤快捷鍵添加鼠標快捷鍵添加縮寫重置為默認快捷鍵 禁用雙快捷鍵用戶快捷鍵的保存位置與操作系統沖突 配置快捷鍵 WebStorm包含預定義的快捷鍵&#xff0c;同時允許自定義快捷鍵。要查看快捷鍵配置&#xff0c;請打開“設置”對話框&#xff0c;然后選擇K…

Java 21 + Spring Boot 3.5:AI驅動的高性能框架實戰

簡介 在微服務架構日益普及的今天,如何構建一個既高性能又具備AI驅動能力的后端系統成為開發者關注的焦點。本篇文章將深入探討Java 21與Spring Boot 3.5的結合,展示如何通過Vector API和JIT優化實現單線程性能提升30%,并利用飛算JavaAI生成智能重試機制和超時控制代碼,解…