国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生

這篇具有很好參考價(jià)值的文章主要介紹了Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

在?Linux?中,進(jìn)程具有獨(dú)立性,進(jìn)程在運(yùn)行后可能 “放飛自我”,這是不利于管理的,于是需要一種約定俗成的方式來(lái)控制進(jìn)程的運(yùn)行,這就是?進(jìn)程信號(hào),本文將會(huì)從什么是進(jìn)程信號(hào)開(kāi)篇,講述各種進(jìn)程信號(hào)的產(chǎn)生方式及作用。

一、信號(hào)是什么

1.1 信號(hào)的概念

信號(hào) 是信息傳遞的承載方式,一種信號(hào)往往代表著一種執(zhí)行動(dòng)作:上課鈴聲,紅綠燈,電話鈴聲

????????當(dāng)然這些都是生活中的 信號(hào),當(dāng)產(chǎn)生這些 信號(hào) 時(shí),我們會(huì)立馬想到對(duì)應(yīng)的 動(dòng)作 ,這是因?yàn)?我們認(rèn)識(shí)并能處理這些信號(hào)

????????我們能進(jìn)行處理是因?yàn)槭苓^(guò)教育,學(xué)習(xí)了執(zhí)行動(dòng)作,但對(duì)進(jìn)程來(lái)說(shuō),它可沒(méi)有接受過(guò)九年義務(wù)教育,也不知道什么時(shí)候該干什么事

????????于是程序員們給操作系統(tǒng)植入了一批 指令,一個(gè)指令表示一種特殊動(dòng)作,而這些指令就是 信號(hào)(進(jìn)程信號(hào))

通過(guò)?kill -l?查看當(dāng)前系統(tǒng)中的信號(hào)集合表

kill -l

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

這些就是當(dāng)前系統(tǒng)中的?進(jìn)程信號(hào),一共?62?個(gè),其中?1~31?號(hào)信號(hào)為?普通信號(hào)(學(xué)習(xí)目標(biāo)),用于?分時(shí)操作系統(tǒng);剩下的?32~64?號(hào)信號(hào)為?實(shí)時(shí)信號(hào),用于?實(shí)時(shí)操作系統(tǒng)

  • 分時(shí)操作系統(tǒng):根據(jù)時(shí)間片實(shí)行公平調(diào)度,適用于個(gè)人電腦
  • 實(shí)時(shí)操作系統(tǒng):高響應(yīng),適合任務(wù)較少、需要快速處理的平臺(tái),比如汽車車機(jī)、火箭發(fā)射控制臺(tái)

普通信號(hào)只保存它有無(wú)產(chǎn)生,實(shí)時(shí)信號(hào)可以保持很長(zhǎng)時(shí)間

因?yàn)槲覀兊南到y(tǒng)屬于?分時(shí)操作系統(tǒng),所以只需要研究?1~31?號(hào)信號(hào)即可,當(dāng)然也不是全部研究,部分信號(hào)只做了解即可

1.2 信號(hào)的作用

早在 《Linux進(jìn)程學(xué)習(xí)【進(jìn)程狀態(tài)】》 我們就已經(jīng)使用過(guò)?信號(hào)?了,比如:

  • kill -9 pid?終止進(jìn)程運(yùn)行
  • kill -19 pid?暫停進(jìn)程運(yùn)行
  • kill -18 pid?恢復(fù)進(jìn)程運(yùn)行

就連常用的?ctrl+c?和?ctrl+d?熱鍵本質(zhì)上也是?信號(hào)

這么多信號(hào),其對(duì)應(yīng)功能是什么呢?

  • 可以通過(guò)?man 7 signal?進(jìn)行查詢

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

其中:

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

1.3 信號(hào)的組成級(jí)原理

進(jìn)程信號(hào)由?信號(hào)編號(hào) + 執(zhí)行動(dòng)作?構(gòu)成,一個(gè)信號(hào)對(duì)應(yīng)一種動(dòng)作,對(duì)于進(jìn)程來(lái)說(shuō),動(dòng)作無(wú)非就這幾種:終止進(jìn)程、暫停進(jìn)程、恢復(fù)進(jìn)程,3?個(gè)信號(hào)就夠用了啊,為什么要搞這么多信號(hào)?

  • 創(chuàng)造信號(hào)的目的不只是控制進(jìn)程,還要便于管理進(jìn)程,進(jìn)程的終止原因有很多種,如果一概而論的話,對(duì)于問(wèn)題分析是非常不友好的,所以才會(huì)將信號(hào)細(xì)分化,搞出這么多信號(hào),目的就是為了方便定位、分析、解決問(wèn)題
  • 并且 普通信號(hào) 就?31?個(gè),這就是意味著所有普通信號(hào)都可以存儲(chǔ)在一個(gè)?int?中,表示是否收到該信號(hào)(信號(hào)的保存)

所以信號(hào)被細(xì)化了,不同的信號(hào)對(duì)應(yīng)不同的執(zhí)行動(dòng)作,雖然大部分最終都是終止進(jìn)程

進(jìn)程的執(zhí)行動(dòng)作是可修改的,默認(rèn)為系統(tǒng)預(yù)設(shè)的?默認(rèn)動(dòng)作

  1. 默認(rèn)動(dòng)作
  2. 忽略
  3. 自定義動(dòng)作

所以我們可以?更改信號(hào)的執(zhí)行動(dòng)作

信號(hào)有這么多個(gè),并且多個(gè)進(jìn)程可以同時(shí)產(chǎn)生多個(gè)信號(hào),操作系統(tǒng)為了管理,先描述、再組織,在?PCB?中增加了 信號(hào)相關(guān)的數(shù)據(jù)結(jié)構(gòu):signal_struct,在這個(gè)結(jié)構(gòu)體中,必然存在一個(gè) 位圖結(jié)構(gòu)?uint32_t signals?存儲(chǔ)?1~31?號(hào)信號(hào)的有無(wú)信息

下面對(duì)?進(jìn)程信號(hào)?做一波概念性的總結(jié):

1.信號(hào)是執(zhí)行的動(dòng)作的信息載體,程序員在設(shè)計(jì)進(jìn)程的時(shí)候,早就已經(jīng)設(shè)計(jì)了其對(duì)信號(hào)的識(shí)別能力
2.信號(hào)對(duì)于進(jìn)程來(lái)說(shuō)是異步的,隨時(shí)可能產(chǎn)生,如果信號(hào)產(chǎn)生時(shí),進(jìn)程在處理優(yōu)先級(jí)更高的事情,那么信號(hào)就不能被立即處理,此時(shí)進(jìn)程需要保存信號(hào),后續(xù)再處理
3.進(jìn)程可以將 多個(gè)信號(hào) 或 還未處理 的信號(hào)存儲(chǔ)在 signal_struct 這個(gè)結(jié)構(gòu)體中,具體信號(hào)編號(hào),存儲(chǔ)在 uint32_t signals 這個(gè)位圖結(jié)構(gòu)中
4.所謂的 “發(fā)送” 信號(hào),其實(shí)就是寫入信號(hào),修改進(jìn)程中位圖結(jié)構(gòu)中對(duì)應(yīng)的比特位,由 0 置為 1,表示該信號(hào)產(chǎn)生了
5.signal_struct 屬于內(nèi)核數(shù)據(jù)結(jié)構(gòu),只能由 操作系統(tǒng) 進(jìn)行同一修改,無(wú)論信號(hào)是如何產(chǎn)生的,最終都需要借助 操作系統(tǒng) 進(jìn)行發(fā)送
6.信號(hào)并不是立即處理的,它會(huì)在合適的時(shí)間段進(jìn)行統(tǒng)一處理

所以?進(jìn)程信號(hào)?可以分為三步:信號(hào)產(chǎn)生 =》 信號(hào)保存 =》 信號(hào)處理

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

------------------------------------------------信號(hào)的產(chǎn)生方式------------------------------------------------

二、鍵盤鍵入

信號(hào)產(chǎn)生(發(fā)送)的第一種方式:鍵盤鍵入,通俗來(lái)說(shuō)就是命令行操作

2.1 ctrl+c 終止前臺(tái)進(jìn)程(前臺(tái)進(jìn)程只有一個(gè))

系統(tǒng)卡死,程序死循環(huán)。這些都是比較常見(jiàn)的問(wèn)題,當(dāng)發(fā)生這些問(wèn)題時(shí),我們可以通過(guò)?鍵盤鍵入?ctrl + c?發(fā)出?2?號(hào)信號(hào)終止前臺(tái)進(jìn)程的運(yùn)行

下面寫一段死循環(huán)代碼:

#include <iostream>
#include <unistd.h>
using namespace std;

int main()
{
    while(true)
    {
        cout << "我是一個(gè)進(jìn)程,我正在運(yùn)行…… PID: " << getpid() << endl;
        sleep(1);
    }

    return 0;
}

運(yùn)行程序后,會(huì)一直循環(huán)打印,此時(shí)如果想要終止進(jìn)程,可以直接按?ctrl + c?發(fā)出?2?號(hào)信號(hào),終止前臺(tái)進(jìn)程

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

此時(shí)發(fā)出了一個(gè)?2?號(hào)信號(hào)?SIGINT?終止了該進(jìn)程的運(yùn)行

如何證明呢?如何證明按?ctrl + c?發(fā)出的是?2?號(hào)信號(hào)呢?

證明自有方法,前面說(shuō)過(guò),一個(gè)信號(hào)配有一個(gè)執(zhí)行動(dòng)作,并且執(zhí)行動(dòng)作是可以修改的,需要用到?signal?函數(shù)(屬于 信號(hào)處理 部分的內(nèi)容,這里需要提前用一下)

ctrl + c?終止的是當(dāng)前正在運(yùn)行的前臺(tái)進(jìn)程,如果在程序運(yùn)行時(shí)加上?&?表示讓其后臺(tái)運(yùn)行,此時(shí)會(huì)發(fā)現(xiàn)無(wú)法終止進(jìn)程

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

像這種后臺(tái)進(jìn)程?ctrl + c?是無(wú)法終止的,可以通過(guò)?kill -9 PID?發(fā)出?9?信號(hào)終止它

2.1.1 signal注冊(cè)執(zhí)行動(dòng)作

signal?函數(shù)可以用來(lái)?修改信號(hào)的執(zhí)行動(dòng)作,也叫注冊(cè)自定義執(zhí)行動(dòng)作

調(diào)用成功返回上一個(gè)執(zhí)行方法的值(其實(shí)就是下標(biāo),后面介紹),失敗則返回?SIG_ERR,并設(shè)置錯(cuò)誤碼

  • 參數(shù)1?待操作信號(hào)的編號(hào)
  • 參數(shù)2?待注冊(cè)的新方法

參數(shù)1?就是信號(hào)編號(hào),為?int,單純地傳遞?信號(hào)名也是可以的,因?yàn)樾盘?hào)名其實(shí)就是信號(hào)編號(hào)的宏定義

參數(shù)2?是一個(gè)函數(shù)指針,意味著需要傳遞一個(gè)?參數(shù)為?int,返回值為空的函數(shù)對(duì)象

  • 參數(shù)?int?是執(zhí)行動(dòng)作的信號(hào)編號(hào)
void handler(int)	//其中的函數(shù)名可以自定義

顯然,signal?函數(shù)是一個(gè)?回調(diào)函數(shù),當(dāng)信號(hào)發(fā)出時(shí),會(huì)去調(diào)用相應(yīng)的函數(shù),也就是執(zhí)行相應(yīng)的動(dòng)作

我們先對(duì)?2?號(hào)信號(hào)注冊(cè)新動(dòng)作,在嘗試按下?ctrl + c,看看它發(fā)出的究竟是不是?2?號(hào)信號(hào)

#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;

void handler(int signo)
{
    cout << "當(dāng)前 " << signo << " 號(hào)信號(hào)正在嘗試執(zhí)行相應(yīng)的動(dòng)作" << endl;
}

int main()
{

    //給 2 號(hào)信號(hào)注冊(cè)新方法
    signal(2, handler);

    while(true)
    {
        cout << "我是一個(gè)進(jìn)程,我正在運(yùn)行…… PID: " << getpid() << endl;
        sleep(1);
    }

    return 0;
}

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

????????當(dāng)我們修改 2 號(hào)信號(hào)的執(zhí)行動(dòng)作后,再次按下 ctrl + c 嘗試終止前臺(tái)進(jìn)程,結(jié)果失敗了!執(zhí)行動(dòng)作變成了我們注冊(cè)的新動(dòng)作

????????這足以證明 ctrl + c 就是在給前臺(tái)進(jìn)程發(fā)出 2 號(hào)信號(hào),ctrl + c 失效后,可以通過(guò) ctrl + \ 終止進(jìn)程,發(fā)出的是 3 號(hào)信號(hào)(3 號(hào)信號(hào)在發(fā)出后,會(huì)生成 核心轉(zhuǎn)儲(chǔ) 文件)

需要注意:

大部分信號(hào)的執(zhí)行動(dòng)作都可以被修改了,但?9?號(hào)信號(hào)沒(méi)有,因?yàn)?9?號(hào)信號(hào)是?SIGKILL,專門用于殺死進(jìn)程,只要是進(jìn)程,他都能干掉

????????19?號(hào)信號(hào)?SIGSTOP?也無(wú)法修改執(zhí)行動(dòng)作,?9?號(hào)?SIGKILL?和?19?號(hào)?SIGSTOP?信號(hào)是很特殊的,經(jīng)過(guò)特殊設(shè)計(jì),不能修改其執(zhí)行動(dòng)作!

2.2 硬件中斷

當(dāng)我們從鍵盤按下?ctrl + c?時(shí),發(fā)生了這些事:CPU?獲取到鍵盤 “按下” 的信號(hào),調(diào)用鍵盤相應(yīng)的 “方法” ,從鍵盤中讀取數(shù)據(jù),讀取數(shù)據(jù)后解析,然后發(fā)出?3?號(hào)信號(hào)

其中?CPU?捕獲鍵盤 “按下” 信號(hào)的操作稱為?硬件中斷

CPU?中有很多的針腳,不同的硬件對(duì)應(yīng)著不同的針腳,每一個(gè)針腳都有自己的編號(hào),硬件與針腳一對(duì)一相連,并通過(guò) 中斷控制器(比如?8259)進(jìn)行控制,當(dāng)我們按下鍵盤后

  • 中斷控制器首先給?CPU?發(fā)送信息,包括鍵盤對(duì)應(yīng)的針腳號(hào)
  • 然后?CPU?將獲取到的針腳號(hào)(中斷號(hào))寫入 寄存器 中
  • 最后根據(jù) 寄存器 里的 中斷號(hào),去 中斷向量表 中查表,找到對(duì)應(yīng)硬件的方法,執(zhí)行它的讀取方法就行了

這樣?CPU?就知道是?鍵盤?發(fā)出的信號(hào),然后就會(huì)去調(diào)用?鍵盤?的執(zhí)行方法,通過(guò)鍵盤的讀取方法,讀取到?ctrl + c?這個(gè)信息,轉(zhuǎn)化后,就是?2?號(hào)信號(hào),執(zhí)行終止前臺(tái)進(jìn)程的動(dòng)作

鍵盤被按下 和 鍵盤哪些位置被按下 是不一樣的

  • 首先鍵盤先按下,CPU?確定對(duì)應(yīng)的讀取方法
  • 其次才是通過(guò)?讀取方法?從鍵盤中讀取數(shù)據(jù)

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

硬件中斷 的流程與 進(jìn)程信號(hào) 的流程雷同,同樣是 先檢測(cè)到信號(hào),然后再去執(zhí)行相應(yīng)的動(dòng)作,不過(guò)此時(shí)發(fā)送的是 中斷信號(hào),執(zhí)行的是 調(diào)用相應(yīng)方法罷了

信號(hào)動(dòng)作 的設(shè)計(jì)方式很實(shí)用,操作系統(tǒng)只需要關(guān)注是否有信號(hào)發(fā)出,發(fā)出后去中斷向量表中調(diào)用相應(yīng)的方法即可,不用管硬件是什么樣、如何變化,做到了 操作系統(tǒng) 與 硬件 間的解耦


三、系統(tǒng)調(diào)用

????????除了可以通過(guò)?鍵盤鍵入?發(fā)送信號(hào)外,還可以通過(guò)直接調(diào)用?系統(tǒng)接口?發(fā)送信號(hào),畢竟?bash?也是一個(gè)進(jìn)程,本質(zhì)上就是在進(jìn)行程序替換而已

3.1 kill函數(shù)

信號(hào)的發(fā)送主要是通過(guò)?kill?函數(shù)進(jìn)行發(fā)送

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

返回值:成功返回?0,失敗返回?-1?并設(shè)置錯(cuò)誤碼

參數(shù)1:待操作進(jìn)程的?PID

參數(shù)2:待發(fā)送的信號(hào)

下面來(lái)簡(jiǎn)單用一下(程序運(yùn)行?5?秒后,自己把自己殺死)

#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;

int main()
{

    int n = 1;
    while (true)
    {

        cout << "我是一個(gè)進(jìn)程,已經(jīng)運(yùn)行了 " << n << " 秒 PID: " << getpid() << endl;
        sleep(1);
        n++;

        if (n > 5)
            kill(getpid(), SIGKILL);
    }

    return 0;
}

kill?函數(shù)當(dāng)然也可以發(fā)送其他信號(hào),這里就不一一展示了,其實(shí)命令行中的?kill?命令就是對(duì)?kill?函數(shù)的封裝,kill -信號(hào)編號(hào) -PID?其中的參數(shù)2、3不正是?kill?函數(shù)所需要的參數(shù)嗎?所以我們可以嘗試自己搞一個(gè)?myKill?命令

3.2 模擬實(shí)現(xiàn) mykill

 1 #include <cstdlib>                                                                                
  2 #include <iostream>
  3 #include <string>
  4 #include <signal.h>
  5 using namespace std;
  6 
  7 void Usage(string proc)
  8 {
  9     // 打印使用信息
 10     cout << "\tUsage: \n\t";
 11     cout << proc << " 信號(hào)編號(hào) 目標(biāo)進(jìn)程" << endl;
 12     exit(2);
 13 }
 14 
 15 int main(int argc, char *argv[])
 16 {
 17     // 參數(shù)個(gè)數(shù)要嚴(yán)格限制
 18     if (argc != 3)
 19     {
 20         Usage(argv[0]);
 21     }
 22 
 23     //獲取兩個(gè)參數(shù)
 24     int signo = atoi(argv[1]);
 25     int pid = atoi(argv[2]);
 26 
 27     //執(zhí)行信號(hào)發(fā)送
 28     kill(pid, signo);
 29 
 30     return 0;
 31 }

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

3.3raise 函數(shù)

發(fā)送信號(hào)的還有一個(gè)?raise?函數(shù),這個(gè)函數(shù)比較奇怪,只能?自己給自己發(fā)信號(hào)

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

返回值:成功返回?0,失敗返回?非0

就只有一個(gè)參數(shù):待發(fā)送的信號(hào)

可以這樣理解:raise?是對(duì)?kill?函數(shù)的封裝,每次傳遞的都是自己的?PID

3.4 abort 函數(shù)

abort?是?C?語(yǔ)言提供的一個(gè)函數(shù),它的作用是?給自己發(fā)送?6?號(hào)?SIGABRT?信號(hào)

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

沒(méi)有返回值,也沒(méi)有參數(shù)

值得一提的是,abort?函數(shù)即使在修改執(zhí)行動(dòng)作后,最后仍然會(huì)發(fā)送?6?號(hào)信號(hào)

同樣是終止進(jìn)程,C語(yǔ)言 還提供了一個(gè)更好用的函數(shù):exit()(頭文件<cstdlib.h>),所以?abort?用的比較少,了解即可

總的來(lái)說(shuō),系統(tǒng)調(diào)用中舉例的這三個(gè)函數(shù)關(guān)系是:kill?包含?raise,raise?包含?abort,作用范圍是在逐漸縮小的

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器


四、軟件條件

信號(hào)產(chǎn)生(發(fā)送)的第三種方式:軟件條件

其實(shí)這種方式我們之前就接觸過(guò)了:管道讀寫時(shí),如果讀端關(guān)閉,那么操作系統(tǒng)會(huì)發(fā)送信號(hào)終止寫端,這個(gè)就是 軟件條件 引發(fā)的信號(hào)發(fā)送,發(fā)出的是?13?號(hào)?SIGPIPE?信號(hào)

五、硬件異常

最后一種產(chǎn)生(發(fā)送)信號(hào)的方式是:硬件異常

所謂?硬件異常?其實(shí)就是我們?cè)趯懗绦蜃畛S龅降母鞣N報(bào)錯(cuò),比如?除 0、野指針

5.1 除 0 導(dǎo)致異常

先來(lái)看一段簡(jiǎn)單的錯(cuò)誤代碼

#include <iostream>
using namespace std;

int main()
{
    int n = 10;
    n /= 0;

    return 0;
}

顯然是會(huì)報(bào)錯(cuò)的是,畢竟?0?不能作為常數(shù)

讓我們通過(guò)?signal?更改?8?號(hào)信號(hào)的執(zhí)行動(dòng)作,嘗試逆天改命,讓?除 0 合法?

#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;

void handler(int signo)
{
    cout << "雖然除 0 了,但我不終止進(jìn)程" << endl;
}

int main()
{
    signal(SIGFPE, handler);
    int n = 10;
    n /= 0;

    return 0;
}

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

結(jié)果:一直在死循環(huán)似的發(fā)送信號(hào),明明只發(fā)生了一次 除 0 行為

想要明白背后的原理,需要先認(rèn)識(shí)一下?狀態(tài)寄存器

5.2 狀態(tài)寄存器

????????在?CPU?中,存在很多?寄存器,其中大部分主要用來(lái)存儲(chǔ)數(shù)據(jù)信息,用于運(yùn)算,除此之外,還存在一種特殊的?寄存器?=》?狀態(tài)寄存器,這個(gè)?寄存器?專門用來(lái)檢測(cè)當(dāng)前進(jìn)程是否出現(xiàn)錯(cuò)誤行為,如果有,就會(huì)把?狀態(tài)寄存器(位圖結(jié)構(gòu))中對(duì)應(yīng)的比特位置?1,意味著出現(xiàn)了 異常

????????當(dāng)操作系統(tǒng)檢測(cè)到?狀態(tài)寄存器?出現(xiàn)異常時(shí),會(huì)根據(jù)其中的值,向出現(xiàn)異常的進(jìn)程?輪詢式?的發(fā)送信號(hào),目的就是讓進(jìn)程退出

????????比如上面的?除 0 代碼,發(fā)生異常后,CPU?將?狀態(tài)寄存器?修改,變成?異常狀態(tài),操作系統(tǒng)檢測(cè)到?異常?后會(huì)向進(jìn)程發(fā)送?8?號(hào)信號(hào),即使我們修改了?8?號(hào)信號(hào)的執(zhí)行動(dòng)作,但?因?yàn)闋顟B(tài)寄存器仍然處于異常狀態(tài),所以操作系統(tǒng)才會(huì)不斷發(fā)送?8?號(hào)信號(hào),所以才會(huì)死循環(huán)式的打印

能讓?狀態(tài)寄存器?變?yōu)?異常?的都不是小問(wèn)題,需要立即終止進(jìn)程,然后尋找、解決問(wèn)題

畢竟如果讓?除 0?變?yōu)楹戏?,那最終的結(jié)果是多少呢?所以操作系統(tǒng)才會(huì)不斷發(fā)送信號(hào),目的就是?終止進(jìn)程的運(yùn)行

5.3 野指針導(dǎo)致異常信號(hào)

除了?除 0?異常外,還有一個(gè)?臭名昭著?的異常:野指針問(wèn)題

#include <iostream>
using namespace std;

int main()
{
    int* ptr = nullptr;
    *ptr = 10;

    return 0;
}

那么?野指針?問(wèn)題是如何引發(fā)的呢?

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

野指針問(wèn)題主要分為兩類:

  1. 指向不該指向的空間
  2. 權(quán)限不匹配,比如只讀的區(qū)域,偏要去寫

共識(shí):在執(zhí)行?*ptr = 10?這句代碼時(shí),首先會(huì)進(jìn)行 虛擬地址 -> 真實(shí)(物理)地址 之間的轉(zhuǎn)換

指向不該指向的空間:這很好理解,就是頁(yè)表沒(méi)有將?這塊虛擬地址空間 與 真實(shí)(物理)地址空間 建立映射關(guān)系,此時(shí)進(jìn)行訪問(wèn)時(shí)?MMU?識(shí)別到異常,于是?MMU?直接報(bào)錯(cuò),操作系統(tǒng)識(shí)別到?MMU?異常后,向?qū)?yīng)的進(jìn)程發(fā)出終止信號(hào)

權(quán)限不匹配:頁(yè)表中除了保存映射關(guān)系外,還會(huì)保存該區(qū)域的權(quán)限情況,比如?是否命中 / RW?等權(quán)限,當(dāng)發(fā)生操作與權(quán)限不匹配時(shí),比如?nullptr?只允許讀取,并不允許其他行為,此時(shí)解引用就會(huì)觸發(fā)?MMU?異常,操作系統(tǒng)識(shí)別到后,同樣會(huì)對(duì)對(duì)應(yīng)的進(jìn)程發(fā)出終止信號(hào)

注:MMU?是內(nèi)存管理單元,主要負(fù)責(zé) 虛擬地址 與 物理地址 間的轉(zhuǎn)換工作,同時(shí)還會(huì)識(shí)別各種異常行為

一旦引發(fā)硬件層面的問(wèn)題,操作系統(tǒng)會(huì)直接發(fā)信號(hào),立即終止進(jìn)程

到目前為止,我們學(xué)習(xí)了很多信號(hào),分別對(duì)應(yīng)著不同的情況,其中有些信號(hào)還反映了異常信息,所以將信號(hào)進(jìn)行細(xì)分,還是很有必要的

六、核心轉(zhuǎn)儲(chǔ)

Linux?中提供了一種系統(tǒng)級(jí)別的能力,當(dāng)一個(gè)進(jìn)程在出現(xiàn)異常的時(shí)候,OS?可以將該進(jìn)程在異常的時(shí)候,核心代碼部分進(jìn)行?核心轉(zhuǎn)儲(chǔ),將內(nèi)存中進(jìn)程的相關(guān)數(shù)據(jù),全部?dump?到磁盤中,一般會(huì)在當(dāng)前進(jìn)程的運(yùn)行目錄下,形成?core.pid?這樣的二進(jìn)制文件(核心轉(zhuǎn)儲(chǔ)?文件)

6.1 核心轉(zhuǎn)儲(chǔ)的概念

對(duì)于某些信號(hào)來(lái)說(shuō),當(dāng)終止進(jìn)程后,需要進(jìn)行?core dump,產(chǎn)生核心轉(zhuǎn)儲(chǔ)文件

比如:3號(hào) SIGQUIT、4號(hào) SIGILL5號(hào) SIGTRAP、6號(hào) SIGABRT、7號(hào) SIGBUS、8號(hào) SIGFPE11號(hào) SIGSEGV、24號(hào) SIGXCPU25號(hào) SIGXFSZ、31號(hào) SIGSYS?都是可以產(chǎn)生核心轉(zhuǎn)儲(chǔ)文件的

不同信號(hào)的動(dòng)作(Action

  • Trem?-> 單純終止進(jìn)程
  • Core?-> 先發(fā)生核心轉(zhuǎn)儲(chǔ),生成核心轉(zhuǎn)儲(chǔ)文件(前提是此功能已打開(kāi)),再終止進(jìn)程

但在前面的學(xué)習(xí)中,我們用過(guò)?3、6、8、11?號(hào)信號(hào),都沒(méi)有發(fā)現(xiàn)?核心轉(zhuǎn)儲(chǔ)?文件啊

難道是我們的環(huán)境有問(wèn)題嗎?

確實(shí),當(dāng)前環(huán)境確實(shí)有問(wèn)題,因?yàn)樗?云服務(wù)器,而?云服務(wù)器?中默認(rèn)是關(guān)閉核心轉(zhuǎn)儲(chǔ)功能的

6.2 打開(kāi)與關(guān)閉核心轉(zhuǎn)儲(chǔ)

通過(guò)指令?ulimit -a?查看當(dāng)前系統(tǒng)中的資源限制情況

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

可以看到,當(dāng)前系統(tǒng)中的核心轉(zhuǎn)儲(chǔ)文件大小為?0,即不生成核心轉(zhuǎn)儲(chǔ)文件

通過(guò)指令手動(dòng)設(shè)置核心轉(zhuǎn)儲(chǔ)文件大小

ulimit -c 1024

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器

現(xiàn)在可以生成核心轉(zhuǎn)儲(chǔ)文件了

6.3 核心轉(zhuǎn)儲(chǔ)的作用

如此大的核心轉(zhuǎn)儲(chǔ)文件有什么用呢?

答案是?調(diào)試

沒(méi)錯(cuò),核心轉(zhuǎn)儲(chǔ)文件可以調(diào)試,并且直接從出錯(cuò)的地方開(kāi)始調(diào)試

這種調(diào)試方式叫做?事后調(diào)試

調(diào)試方法:

  1. gcc / g++?編譯時(shí)加上?-g?生成可調(diào)試文件
  2. 運(yùn)行程序,生成?core-dump?文件
  3. gdb 程序?進(jìn)入調(diào)試模式
  4. core-file core.file?利用核心轉(zhuǎn)儲(chǔ)文件,快速定位至出錯(cuò)的地方

Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生,linux,運(yùn)維,服務(wù)器文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-832939.html

到了這里,關(guān)于Linux進(jìn)程(一)信號(hào)-----信號(hào)產(chǎn)生的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Linux入門之進(jìn)程信號(hào)|信號(hào)產(chǎn)生的方式

    Linux入門之進(jìn)程信號(hào)|信號(hào)產(chǎn)生的方式

    文章目錄 一、信號(hào)入門 1.linux信號(hào)的基本概念 2.使用kill -l 命令可以查看系統(tǒng)定義的信號(hào)列表 3.信號(hào)處理常見(jiàn)方式 二、產(chǎn)生信號(hào) 1.通過(guò)終端按鍵產(chǎn)生信號(hào) 2.通過(guò)調(diào)用系統(tǒng)函數(shù)向進(jìn)程發(fā)信號(hào) 3.由軟條件產(chǎn)生信號(hào) 4.硬件異常產(chǎn)生信號(hào) ??? 1. /0異常 ??? 2.模擬野指針 信號(hào)是進(jìn)程之

    2024年02月09日
    瀏覽(21)
  • 【Linux】進(jìn)程信號(hào)——進(jìn)程信號(hào)的概念和介紹、產(chǎn)生信號(hào)、四種產(chǎn)生信號(hào)方式、阻塞信號(hào)、捕捉信號(hào)、阻塞和捕捉信號(hào)的函數(shù)

    【Linux】進(jìn)程信號(hào)——進(jìn)程信號(hào)的概念和介紹、產(chǎn)生信號(hào)、四種產(chǎn)生信號(hào)方式、阻塞信號(hào)、捕捉信號(hào)、阻塞和捕捉信號(hào)的函數(shù)

    ??在Linux中,進(jìn)程信號(hào)是一種異步的事件通知機(jī)制,用于通知進(jìn)程某個(gè)事件已經(jīng)發(fā)生。它是進(jìn)程間通信的一種方式,可以用來(lái)控制進(jìn)程的行為。 ??當(dāng)一個(gè)進(jìn)程收到信號(hào)時(shí),操作系統(tǒng)會(huì)中斷該進(jìn)程的正??刂屏鞒蹋?zhí)行相應(yīng)的處理函數(shù)。進(jìn)程收到信號(hào)后有三種處理方式:

    2024年02月02日
    瀏覽(27)
  • 【Linux】進(jìn)程信號(hào) --- 信號(hào)的產(chǎn)生 保存 捕捉遞達(dá)

    【Linux】進(jìn)程信號(hào) --- 信號(hào)的產(chǎn)生 保存 捕捉遞達(dá)

    被愛(ài)情困住的是傻子 1. 關(guān)于信號(hào)這個(gè)話題我們其實(shí)并不陌生,早在以前的時(shí)候,我們想要?dú)⑺滥硞€(gè)后臺(tái)進(jìn)程的時(shí)候,無(wú)法通過(guò)ctrl+c熱鍵終止進(jìn)程時(shí),我們就會(huì)通過(guò)kill -9的命令來(lái)殺死信號(hào)。 查看信號(hào)也比較簡(jiǎn)單,通過(guò)kill -l命令就可以查看信號(hào)的種類,雖然最大的信號(hào)編號(hào)是

    2023年04月23日
    瀏覽(22)
  • 【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送

    【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送

    kill -l 是一個(gè)在 Linux 和 Unix 系統(tǒng)中使用的命令,用于列出可用的信號(hào)列表。 在Linux和Unix系統(tǒng)中,進(jìn)程可以通過(guò)發(fā)送信號(hào)來(lái)與其他進(jìn)程或操作系統(tǒng)交互。kill 命令可以向指定的進(jìn)程發(fā)送一個(gè)特定的信號(hào),以便對(duì)其進(jìn)行控制,例如終止進(jìn)程或重新啟動(dòng)進(jìn)程等。 kill -l 命令會(huì)列出可

    2024年02月16日
    瀏覽(59)
  • 運(yùn)維記錄 會(huì)產(chǎn)生無(wú)用日志的服務(wù)器

    創(chuàng)建linux定時(shí)任務(wù) crontab -e cron表達(dá)式 文件名.sh 查看linux定時(shí)任務(wù) crontab -l 確認(rèn)創(chuàng)建完成后重啟cron service crond restart

    2024年04月11日
    瀏覽(18)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.16(進(jìn)程信號(hào) —— 信號(hào)產(chǎn)生 | 信號(hào)發(fā)送 | 核心轉(zhuǎn)儲(chǔ))

    【探索Linux】—— 強(qiáng)大的命令行工具 P.16(進(jìn)程信號(hào) —— 信號(hào)產(chǎn)生 | 信號(hào)發(fā)送 | 核心轉(zhuǎn)儲(chǔ))

    在現(xiàn)代社會(huì)中,信號(hào)無(wú)處不在。我們的生活充滿了各種各樣的信號(hào),它們指引著我們前進(jìn)的方向,使我們能夠了解周圍環(huán)境的變化。正如在計(jì)算機(jī)編程中一樣,Linux進(jìn)程信號(hào)也是一種重要的信號(hào),它們扮演著相似的角色。 想象一下,在繁忙的城市街道上行駛,交通信號(hào)燈是我

    2024年02月05日
    瀏覽(18)
  • 【Linux】進(jìn)程信號(hào)(完整版) --- 信號(hào)產(chǎn)生 信號(hào)保存 信號(hào)捕捉 可重入函數(shù) volatile SIGCHLD信號(hào)等

    【Linux】進(jìn)程信號(hào)(完整版) --- 信號(hào)產(chǎn)生 信號(hào)保存 信號(hào)捕捉 可重入函數(shù) volatile SIGCHLD信號(hào)等

    ?? 作者: 阿潤(rùn)菜菜 ?? 專欄: Linux系統(tǒng)編程 我們想要?dú)⑺滥硞€(gè)后臺(tái)進(jìn)程的時(shí)候,無(wú)法通過(guò)ctrl+c熱鍵終止進(jìn)程時(shí),我們就會(huì)通過(guò)kill -9的命令來(lái)殺死信號(hào)。 查看信號(hào)也比較簡(jiǎn)單,通過(guò) kill -l 命令就可以查看所有信號(hào)的種類,雖然最大的信號(hào)編號(hào)是64,但實(shí)際上所有信號(hào)只有6

    2024年02月04日
    瀏覽(26)
  • 運(yùn)維 | 查看 Linux 服務(wù)器 IP 地址

    大多數(shù)在操作 Linux 系統(tǒng)時(shí),我們經(jīng)常需要知道服務(wù)器的 IP 比便于后續(xù)的一系列操作,這時(shí)候有快速查看主機(jī) IP 的命令行操作,能夠有效的幫助我們 本章節(jié)主要記錄一些常用查看服務(wù)器 IP 的命令,希望對(duì)大家有所幫助。 查看 Linux 服務(wù)器的 IP 地址的命令大體上有以下幾種。

    2024年04月27日
    瀏覽(104)
  • 【運(yùn)維】Linux 跨服務(wù)器復(fù)制文件文件夾

    如果是云服務(wù) 建議用內(nèi)網(wǎng)ip scp是secure copy的簡(jiǎn)寫,用于在Linux下進(jìn)行遠(yuǎn)程拷貝文件的命令,和它類似的命令有cp,不過(guò)cp只是在本機(jī)進(jìn)行拷貝不能跨服務(wù)器,而且scp傳輸是加密的??赡軙?huì)稍微影響一下速度。當(dāng)你服務(wù)器硬盤變?yōu)橹蛔x read only system時(shí),用scp可以幫你把文件移出來(lái)

    2024年02月08日
    瀏覽(109)
  • linux并發(fā)服務(wù)器 —— 多進(jìn)程并發(fā)(四)

    linux并發(fā)服務(wù)器 —— 多進(jìn)程并發(fā)(四)

    程序是包含一系列信息的文件,描述了如何在運(yùn)行時(shí)創(chuàng)建一個(gè)進(jìn)程; 進(jìn)程是正在運(yùn)行的程序的實(shí)例,可以用一個(gè)程序來(lái)創(chuàng)建多個(gè)進(jìn)程; 用戶內(nèi)存空間包含程序代碼以及代碼所使用的變量,內(nèi)核數(shù)據(jù)結(jié)構(gòu)用于維護(hù)進(jìn)程狀態(tài)信息; 進(jìn)程控制塊(PCB):維護(hù)進(jìn)程相關(guān)的信息,tas

    2024年02月11日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包