中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

做淘寶網(wǎng)站java代碼站長工具seo綜合查詢分析

做淘寶網(wǎng)站java代碼,站長工具seo綜合查詢分析,簡述營銷型網(wǎng)站開發(fā)流程,政府內(nèi)部網(wǎng)站建設(shè)方案文章目錄 正文前的知識準(zhǔn)備kill 命令查看信號man手冊查看信號信號的處理方法 認(rèn)識信號產(chǎn)生的5種方式1. 工具2. 鍵盤3. 系統(tǒng)調(diào)用kill 向任意進(jìn)程發(fā)送任意信號raise 給調(diào)用方發(fā)送任意信號abort 給調(diào)用方發(fā)送SIGABRT信號 4. 軟件條件5. 異常 正文前的知識準(zhǔn)備 kill 命令查看信號 …

文章目錄

  • 正文前的知識準(zhǔn)備
    • kill 命令查看信號
    • man手冊查看信號
    • 信號的處理方法
  • 認(rèn)識信號產(chǎn)生的5種方式
    • 1. 工具
    • 2. 鍵盤
    • 3. 系統(tǒng)調(diào)用
      • kill 向任意進(jìn)程發(fā)送任意信號
      • raise 給調(diào)用方發(fā)送任意信號
      • abort 給調(diào)用方發(fā)送SIGABRT信號
    • 4. 軟件條件
    • 5. 異常

正文前的知識準(zhǔn)備

kill 命令查看信號

在命令行終端輸入命令kill -l快速查看信號列表
在這里插入圖片描述

信號列表中的每一項(xiàng)都由【數(shù)字】和【名字】兩部分構(gòu)成,但是信號本質(zhì)上就只是一個(gè)【數(shù)字】而已,【名字】只是一個(gè)宏,如何證明,看源碼定義:
在這里插入圖片描述

信號列表中一共有62個(gè)信號,沒有0、32、33號信號,信號可以分成實(shí)時(shí)信號(34 ~ 64)和非實(shí)時(shí)信號(1 ~ 31),后面談到的所有內(nèi)容只涉及非實(shí)時(shí)信號。

man手冊查看信號

kill -l只是簡單羅列一下OS中有哪些信號而已,這種方式不足以了解到更多的知識,還有另外一種查看信號的方式——man 手冊。

man 7 signal 命令可用于查看 Linux 中有關(guān)信號的手冊頁。這個(gè)命令會顯示與信號相關(guān)的信息,其中包含了關(guān)于信號的詳細(xì)信息,如信號的編號、名稱、含義、默認(rèn)處理方式等,可以更好地理解信號的概念和用法。(文章后面的很多地方都會用到表里的內(nèi)容)
在這里插入圖片描述

信號的處理方法

信號的完整生命周期通常分為3個(gè)階段:信號的產(chǎn)生、信號的保存、信號的處理。
本來信號的處理不是放在文章的內(nèi)容,但是為了更好的理解信號產(chǎn)生的現(xiàn)象,這里提前了解一下。在這里插入圖片描述

信號的處理方法有三種:

  1. 默認(rèn):man手冊中提到,OS為每個(gè)信號都設(shè)置了一個(gè)默認(rèn)行為,當(dāng)一個(gè)進(jìn)程收到信號時(shí)會執(zhí)行對應(yīng)的行為。
  2. 自定義捕捉:當(dāng)進(jìn)程收到一個(gè)信號,不執(zhí)行默認(rèn)行為轉(zhuǎn)而執(zhí)行程序員指定的行為,這個(gè)過程稱之為 “自定義捕捉”。
  3. 忽略:進(jìn)程收到信號之后什么都不做,即忽略該信號。

這里介紹一個(gè)能夠更改進(jìn)程信號處理方法的系統(tǒng)調(diào)用signal。

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

說明:

  • 使用該方法要包含頭文件signal.h。
  • sighandler_t是一個(gè)函數(shù)指針,指向的函數(shù)參數(shù)個(gè)數(shù)為1,參數(shù)類型為int,返回值類型為sighandler_t。
  • signum是指某個(gè)信號,表示對該信號設(shè)置自定義處理方法。
  • handler是程序員對信號signum的自定義處理方法。
  • 該方法的作用是將進(jìn)程收到信號signum的處理動作由默認(rèn)改為程序員自定義的handler方法,即當(dāng)進(jìn)程收到信號signum時(shí),不再執(zhí)行默認(rèn)的處理動作,轉(zhuǎn)而執(zhí)行程序員自定義的handler方法來處理處理信號signum。

注意:signal被調(diào)用時(shí),handler方法不會被立即執(zhí)行,而是進(jìn)程收到信號之后才會被執(zhí)行,如果沒有收到對應(yīng)的信號,handler方法永遠(yuǎn)也不會執(zhí)行。

認(rèn)識信號產(chǎn)生的5種方式

1. 工具

第一種信號產(chǎn)生的手段就是Linux操作系統(tǒng)內(nèi)置的 kill 工具,通過該工具能夠做到向任意進(jìn)程發(fā)送任意信號。

LJH@hecs-66624:~$ ll /usr/bin/kill
-rwxr-xr-x 1 root root 30952 Sep  9  2021 /usr/bin/kill*

通常,kill命令的使用形式是

kill -<信號編號> <進(jìn)程ID>

例如,輸入命令 kill -9 1234,kill 工具會向 ID 為 1234 的進(jìn)程發(fā)送 SIGKILL 信號,SIGKILL 信號的默認(rèn)行為強(qiáng)制終止進(jìn)程。

再介紹一下2號信號 SIGINT,它的默認(rèn)處理動作的 Term(terminate,終止),即終止一個(gè)正在運(yùn)行的進(jìn)程。

這里就通過一個(gè)實(shí)現(xiàn)來驗(yàn)證一下kill命令能否對一個(gè)進(jìn)程發(fā)送信號,同時(shí)還演示一下該如何使用系統(tǒng)調(diào)用signal來設(shè)置進(jìn)程的信號處理方法。


實(shí)驗(yàn)內(nèi)容如下:

  1. 寫一個(gè)程序死循環(huán)向顯示器輸出 "I am working, my pid is " + 進(jìn)程 ID。
  2. 在 1 的基礎(chǔ)上,通過kill工具發(fā)送 2 號信號 SIGINT 來終止該進(jìn)程,驗(yàn)證進(jìn)程處理信號 SIGINT 的默認(rèn)動作。
  3. 在 1 的基礎(chǔ)上,先調(diào)用signal將進(jìn)程對信號 SIGINT 的處理動作設(shè)置為向顯示器輸出 "get a signal: " + 收到的信號的數(shù)字、然后退出,再進(jìn)程執(zhí)行過程中向該進(jìn)程發(fā)送信號 SIGINT,如果輸出 “get a signal: 2” 并退出,則說明猜測正確。
  4. 在 1 的基礎(chǔ)上,調(diào)用signal將進(jìn)程對信號SIGINT的處理動作設(shè)置為忽略,然后在進(jìn)程運(yùn)行過程中向該信號發(fā)送信號SIGINT,如果信號發(fā)送無效,則說明猜測正確。

實(shí)驗(yàn)第2步:
代碼:

// cpp
#include <iostream>
// system call
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;int main()
{while (true){cout << "I am working, my pid is " << getpid() << endl;sleep(2);}return 0;
}

運(yùn)行過程:
在這里插入圖片描述

結(jié)論:驗(yàn)證成功,進(jìn)程處理信號SIGINT的默認(rèn)動作確實(shí)是終止。


實(shí)驗(yàn)第3步
代碼:

#include <iostream>
#include <cstdlib>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;void handler(int signum)
{cout << "get a signal: " << signum << endl;exit(0);
}int main()
{signal(SIGINT, handler);while (true){cout << "I am working, my pid is " << getpid() << endl;sleep(2);}return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

結(jié)論:驗(yàn)證成功,實(shí)現(xiàn)了對信號SIGINT的自定義捕捉。


實(shí)驗(yàn)第4步
SIG_IGN的定義:

#define	SIG_IGN	 ((__sighandler_t)  1)	/* Ignore signal.  */

代碼:

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;int main()
{signal(SIGINT, SIG_IGN);while (true){cout << "I am working, my pid is " << getpid() << endl;sleep(2);}return 0;
}

運(yùn)行結(jié)果
在這里插入圖片描述

結(jié)論:驗(yàn)證成功,實(shí)現(xiàn)了對信號SIGINT的忽略操作。

2. 鍵盤

Ctrl+C這個(gè)組合鍵是我們在Linux最常用的組合鍵之一,它能終止正在執(zhí)行過程中的進(jìn)程,就像下面這樣:
在這里插入圖片描述

對于Ctrl+C這個(gè)組合鍵,我們雖然會用,但是卻不怎么了解它的原理,既然這里提到了它,就說明它的原理和信號有關(guān),理由是我們輸入Ctrl+C組合鍵被操作系統(tǒng)解析成SIGINT信號,然后發(fā)送給了正在運(yùn)行的進(jìn)程,SIGINT信號的默認(rèn)動作是終止進(jìn)程,所以死循環(huán)被終止了。

詳細(xì)的原理可以看一下個(gè)人寫的另外一篇文章《解析Linux鍵盤組合鍵產(chǎn)生信號的完整過程:從硬件中斷到信號發(fā)送》

憑什么這么說?接下來就要用一個(gè)實(shí)驗(yàn)來驗(yàn)證這個(gè)結(jié)論是否正確。


實(shí)驗(yàn)內(nèi)容如下:
寫一個(gè)程序,內(nèi)容是死循環(huán)向顯示器輸出 "I am working, my pid is " + 進(jìn)程ID,同時(shí)調(diào)用signal設(shè)置對信號SIGINT的捕捉方法為向顯示器輸出 "get a signal: " + 信號數(shù)字,但是不退出,進(jìn)程執(zhí)行過程中,不斷按下ctrl + c,觀察實(shí)驗(yàn)現(xiàn)象,如果信號數(shù)字是2,就說明收到了信號SIGINT,結(jié)論正確。

代碼:

#include <iostream>
#include <cstdlib>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;void handler(int signum)
{cout << "get a signal: " << signum << endl;// exit(0);
}int main()
{signal(SIGINT, handler);while (true){cout << "I am working, my pid is " << getpid() << endl;sleep(2);}return 0;
}

運(yùn)行結(jié)果:
這里能夠看到在進(jìn)程給執(zhí)行過程中,連續(xù)按下Ctrl+C,自定義的handler方法不斷被執(zhí)行,然后向屏幕輸出收到了2號信號,說明了上面的結(jié)論是正確的。
在這里插入圖片描述


于此同時(shí),再分別看一下源碼中對信號SIGINT的定義中的注釋和man手冊對SIGINT的描述

#define	SIGINT		2	/* Interactive attention signal.  */Signal      Standard   Action   Comment
────────────────────────────────────────────────────────────────────────
SIGINT       P1990      Term    Interrupt from keyboard

“Interactive Interrupt Signal”,交互式中斷信號,強(qiáng)調(diào)了它是通過用戶的交互操作觸發(fā)的,用于引起程序的注意并中斷執(zhí)行,而man手冊中 “Interrupt from keyboard” 的注釋表明,這個(gè)“交互操作”指的就是 Ctrl+C 這個(gè)組合鍵,Action 項(xiàng)為 Term 表示默認(rèn)行為是終止進(jìn)程。

3. 系統(tǒng)調(diào)用

在第2點(diǎn)時(shí)提到,shell程序通過系統(tǒng)調(diào)用來向目標(biāo)進(jìn)程發(fā)送信號,而系統(tǒng)調(diào)用就是產(chǎn)生信號的第3種方式,所以接下來說一下,都有哪些系統(tǒng)調(diào)用可以發(fā)送信號(說是系統(tǒng)調(diào)用,但其實(shí)這里只會講到一個(gè)系統(tǒng)調(diào)用,其余兩個(gè)都是C的庫函數(shù),不過它們兩個(gè)的底層都是封裝了系統(tǒng)調(diào)用,而且3者都是通過代碼的形式來實(shí)現(xiàn)信號發(fā)送,所以這里就一起介紹)。

kill 向任意進(jìn)程發(fā)送任意信號

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

kill 系統(tǒng)調(diào)用的功能是向指定的進(jìn)程發(fā)送指定的信號,參數(shù)pid是目標(biāo)進(jìn)程ID,參數(shù)sig是待發(fā)送信號,信號發(fā)送成功,返回值為0,信號發(fā)送失敗,返回值為-1,同時(shí)錯(cuò)誤碼(errno)被設(shè)置。

理論部分完了,接下來是實(shí)驗(yàn)驗(yàn)證,到底 kill 系統(tǒng)調(diào)用能不能向一個(gè)進(jìn)程發(fā)送信號。

實(shí)驗(yàn)內(nèi)容:
使用 kill 系統(tǒng)調(diào)用簡單實(shí)現(xiàn)一個(gè)屬于自己的 kill 命令,即 mykill,輸入 ./mykill -<信號編號> <進(jìn)程ID> 能夠做到和 kill 命令一樣的功能,然后啟動一個(gè)死循環(huán)輸出 "I am working, my pid is " + 進(jìn)程ID 的程序,在另一個(gè)窗口向該該進(jìn)程發(fā)送信號SIGKILL,如果死循環(huán)進(jìn)程 Killed,說明 kill 系統(tǒng)調(diào)用確實(shí)能夠向一個(gè)進(jìn)程發(fā)送信號。

代碼:

---------------./testsig-----------------------
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;int main()
{while (true){cout << "I am working, my pid is " << getpid() << endl;sleep(1);}return 0;
}---------------./mykill------------------------
#include <iostream>
#include <string>
#include <cstring>
#include <cerrno>
#include <signal.h>
#include <sys/types.h>using namespace std;// ./mykill -9 pid
int main(int argc, char* argv[])
{if (argc != 3){cout << "Usage: " << argv[0] << " -signumber pid" << endl;return 1;}int signumber = stoi(argv[1]+1);int pid = stoi(argv[2]);int n = kill(pid, signumber);if (n < 0){cout << "kill error, error message: " << strerror(errno) << endl;return 2;}return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

raise 給調(diào)用方發(fā)送任意信號

#include <signal.h>
int raise(int sig);

raise 方法還有下面的 abort 方法嚴(yán)格上來說不算是系統(tǒng)調(diào)用,但都屬于調(diào)用函數(shù)發(fā)送信號的范疇,并且比較常見,這里也一起研究一下。raise 方法的作用是給調(diào)用 raise 的進(jìn)程發(fā)送一個(gè)指定的信號 sig,發(fā)送成功返回0,發(fā)送失敗返回一個(gè)非0整數(shù)。

使用演示:
寫一個(gè)程序,每秒向顯示器輸出 "I am working, my pid is " + 進(jìn)程ID,3秒后向自己發(fā)送信號SIGKILL。

代碼:

#include <iostream>
#include <cstdlib>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;int main()
{int cnt = 0;while (true){if (cnt == 3) {cout << "raise: send SIGKILL to caller" << endl;raise(SIGKILL);}cout << "I am working, my pid is " << getpid() << endl;cnt++;sleep(1);}return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

abort 給調(diào)用方發(fā)送SIGABRT信號

#include <stdlib.h>
void abort(void);

說明:
abort 方法會向調(diào)用該方法的進(jìn)程發(fā)送 SIGABRT 信號,SIGABRT 的全稱是 “Signal Abort”,“abort” 的中文意思是 “中止” 或 “放棄”,在計(jì)算機(jī)術(shù)語中指的是異常終止程序的行為,所以,進(jìn)程處理信號 SIGABRT 的默認(rèn)動作就是終止進(jìn)程。


代碼驗(yàn)證及使用演示:

#include <iostream>
#include <cstdlib>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;void handler(int signo)
{std::cout << "get a signo: " << signo << std::endl;exit(0);
}int main()
{signal(SIGABRT, handler);int cnt = 0;while (true){if (cnt == 3) {cout << "abort: send SIGABRT to caller" << endl;abort();}cout << "I am working, my pid is " << getpid() << endl;cnt++;sleep(1);}return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

4. 軟件條件

產(chǎn)生信號的第4種方式就是【軟件條件】,相比起前三種,這個(gè)看起來就很抽象,個(gè)人是這樣理解的:在 “軟件條件產(chǎn)生信號” 中,“軟件” 指的是各種進(jìn)程或者程序。當(dāng)某個(gè)進(jìn)程滿足了某種條件,比如一個(gè)錯(cuò)誤的操作、一個(gè)特定的事件發(fā)生或者一個(gè)狀態(tài)的改變,它可能會向其他進(jìn)程、操作系統(tǒng)或者它自己發(fā)送一個(gè)信號,以通知它們發(fā)生了某個(gè)事件或者需要采取某種行動。

下面來講一個(gè)經(jīng)典的軟件條件的例子,13號 管道信號 SIGPIPE:

管道是進(jìn)程間通信的手段之一,管道本身是OS提供的基于文件系統(tǒng)實(shí)現(xiàn)的一段內(nèi)核級文件緩沖區(qū),進(jìn)程A先將數(shù)據(jù)寫入緩沖區(qū)中,進(jìn)程B來讀取這樣就實(shí)現(xiàn)了兩個(gè)進(jìn)程間的通信。

而一個(gè)管道只能支持單向通信,換言之,通信的進(jìn)程雙方得協(xié)商誰是管道的寫端,誰是管道的讀端,講這個(gè)有意義嗎,有意義,因?yàn)楣艿劳ㄐ胖幸?guī)定了這樣一種情況,當(dāng)管道的讀端進(jìn)程關(guān)閉了管道的讀端之后,OS會強(qiáng)制終止寫端進(jìn)程,因?yàn)楣艿罃?shù)據(jù)已經(jīng)沒人讀取了,再寫也已經(jīng)沒有意義。

在這里插入圖片描述

上面是結(jié)論,中間的原理是這樣的,管道本身是OS提供用于進(jìn)程間通信的資源,OS內(nèi)部有通信需求的進(jìn)程肯定不止這兩個(gè),所以,OS內(nèi)肯定會創(chuàng)建很多的管道資源來 為進(jìn)程提供通信服務(wù),而OS作為計(jì)算機(jī)軟硬件資源的管理者,它內(nèi)部肯定會有一個(gè)描述管道信息的結(jié)構(gòu)體以及組織管理所有管道的數(shù)據(jù)結(jié)構(gòu),因此,當(dāng)某個(gè)管道的讀端進(jìn)程將管道的讀端關(guān)閉了,OS肯定就會知道并將描述管道信息的結(jié)構(gòu)體對象內(nèi)的信息做修改,當(dāng)該管道的寫端進(jìn)程嘗試寫入數(shù)據(jù)時(shí),OS會檢查管道的狀態(tài),如果發(fā)現(xiàn)該進(jìn)程滿足 “ 向不滿足寫入條件的管道進(jìn)行寫入 ” 的條件時(shí),OS就會向該進(jìn)程發(fā)送 SIGPIPE 信號,通知它寫入操作失敗,該進(jìn)程需要處理這個(gè)信號。

首先來看一下man手冊對于 SIGPIPE 信號的描述

Signal      Standard   Action   Comment
────────────────────────────────────────────────────────────────────────
SIGPIPE      P1990      Term    Broken pipe: write to pipe with no readers; see pipe(7)

其次慣例操作實(shí)驗(yàn)驗(yàn)證,內(nèi)容如下:

  • pipe_server進(jìn)程作為管道的讀端,從管道中讀取數(shù)據(jù)并輸出,讀端進(jìn)程會在運(yùn)行3秒后退出
  • pipe_client進(jìn)程作為管道的寫端,不停向管道寫入數(shù)據(jù),同時(shí)寫端進(jìn)程對SIGPIPE信號做自定義捕捉,看是否真的收到了SIGPIPE信號。

代碼如下:

---------------Command.hpp------------------------
#ifndef __COMMAND_HPP__
#define __COMMAND_HPP__#include <iostream>
#include <string>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>using std::cerr;
using std::cin;
using std::cout;
using std::endl;
#define Mode 0666class Fifo
{
public:Fifo(const char *path) : _path(path){umask(0);int n = mkfifo(_path.c_str(), Mode);if (n == 0){cout << "mkfifo success" << endl;}else{cerr << "mkfifo failed, errno: " << errno << ", errmsg: " << strerror(errno) << endl;exit(1);}}~Fifo(){int n = unlink(_path.c_str());if (n == 0){cout << "remove fifo success" << endl;}else{cerr << "remove fifo failed, errno: " << errno << ", errmsg: " << strerror(errno) << endl;exit(1);}}protected:std::string _path;
};#endif
---------------PipeServer.cc------------------------
#include "Command.hpp"const char *path = "fifo";int main()
{// 創(chuàng)建管道Fifo fifo(path);// 獲取管道讀端int rfd = open("fifo", O_RDONLY);if (rfd >= 0){cout << "open fifo success" << endl;}else{cerr << "open fifo failed, errno: " << errno << ", errmsg: " << strerror(errno) << endl;exit(1);}// 讀數(shù)據(jù)char buffer[1024]{0};int cnt = 4;while (cnt--){ssize_t n = read(rfd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = 0;cout << "get msg from client: " << buffer << endl;}else if (n == 0){cout << "client quit, me too!" << endl;break;}else{cerr << "read from fifo failed, errno: " << errno << ", errmsg: " << strerror(errno) << endl;break;}}close(rfd);return 0;
}
---------------PipeClient.cc------------------------
#include "Command.hpp"void handler(int signum)
{cout << "get a signum: " << signum << endl;cout << "Pipe is broken, now I quit" << endl;exit(1);
}int main()
{signal(SIGPIPE, handler);// 獲取管道寫端int wfd = open("fifo", O_WRONLY);if (wfd >= 0){cout << "open fifo success" << endl;}else{cerr << "open fifo failed, errno: " << errno << ", errmsg: " << strerror(errno) << endl;exit(1);}// 發(fā)消息const char *inbuffer = "I am process A and I am client";while (true){ssize_t n = write(wfd, inbuffer, strlen(inbuffer));if (n < 0){cerr << "write to fifo failed, errno: " << errno << ", errmsg: " << strerror(errno) << endl;break;}sleep(1);}close(wfd);return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述
在這里插入圖片描述

5. 異常

了解過進(jìn)程的都知道,一個(gè)進(jìn)程退出只會有以下3種場景:

  1. 代碼運(yùn)行完畢,結(jié)果正確。
  2. 代碼運(yùn)行完畢,結(jié)果不正確。
  3. 代碼運(yùn)行過程中,進(jìn)程異常終止。

而異常終止的本質(zhì)原因是因?yàn)檫M(jìn)程收到了信號,所以,第5種產(chǎn)生信號的方式就是異常。

舉兩個(gè)常見的代碼異常,進(jìn)程收到信號的例子:

  1. 代碼除零 8) SIGFPE

下面是一段演示代碼,里面寫了除零操作。

#include <iostream>
using namespace std;int main()
{int a = 10;a /= 0;return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

運(yùn)行之后看到,程序輸出 “Floating point exception (core dumped)” 后就結(jié)束了,為了確認(rèn)其是否收到了信號,這里使用signal設(shè)置自定義捕捉 SIGFPE 信號,代碼修改如下:

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>using namespace std;void handler(int signum)
{cout << "get a signum: " << signum << endl;sleep(1);
}int main()
{signal(SIGFPE, handler);int a = 10;a /= 0;return 0;
}

輸出結(jié)果:
在這里插入圖片描述

捕捉了之后,確實(shí)驗(yàn)證了進(jìn)程收到了 SIGFPE 信號,但同時(shí)也看到了一個(gè)很奇怪的現(xiàn)象,明明代碼里從頭到尾都沒有寫循環(huán),為什么handler方法會被一直執(zhí)行?

理由:信號的處理方法從Core退出被改成的向顯示器輸出一句話,這就導(dǎo)致了原本該退出的進(jìn)程沒有退出,進(jìn)程沒有退出,除零異常就一直存在,進(jìn)程在被CPU調(diào)度時(shí)就會一直觸發(fā)異常,OS會不斷地向進(jìn)程發(fā)送 SIGFPE 信號,進(jìn)程收到信號并處理就會一直向屏幕輸出,導(dǎo)致了一種死循環(huán)的局面。

  1. 野指針 11) SIGEGV

下面是一份演示代碼,里面寫了野指針訪問操作。

#include <iostream>
using namespace std;int main()
{int *p = nullptr;*p = 100;return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

運(yùn)行之后看到,程序輸出 “Segmentation fault (core dumped)” 后直接退出,為了驗(yàn)證進(jìn)程是否真的收到了信號,設(shè)置自定義捕捉 SIGSEGV 信號,觀察是否收到信號,代碼修改如下:

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
using namespace std;void handler(int signum)
{cout << "get a signum: " << signum << endl;sleep(1);
}int main()
{signal(SIGSEGV, handler);int *p = nullptr;*p = 100;return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

http://www.risenshineclean.com/news/22789.html

相關(guān)文章:

  • 網(wǎng)站申請域名在線代理瀏覽網(wǎng)頁
  • 如何找人幫我做網(wǎng)站推廣百度熱門關(guān)鍵詞排名
  • 阿里巴巴網(wǎng)站怎么做推廣方案網(wǎng)站排名優(yōu)化推廣
  • 2024房價(jià)即將暴漲十大城市重慶seo優(yōu)化公司
  • 男女做暖暖的試看網(wǎng)站大全安徽seo推廣公司
  • 有哪些專做自然風(fēng)景圖片的網(wǎng)站百度信息流投放在哪些平臺
  • 網(wǎng)站搭建教學(xué)小吳seo博客
  • 互動平臺羅馬復(fù)興廣州seo站內(nèi)優(yōu)化
  • 公司做網(wǎng)站需要準(zhǔn)備什么東西整合營銷策略有哪些
  • 珠海移動網(wǎng)站建設(shè)報(bào)價(jià)網(wǎng)站制作公司怎么找
  • 網(wǎng)站開發(fā)線框四年級下冊數(shù)學(xué)優(yōu)化設(shè)計(jì)答案
  • 阿拉丁建站系統(tǒng)谷歌網(wǎng)站優(yōu)化推廣
  • 愛做片視頻網(wǎng)站百度收錄入口
  • 做網(wǎng)站上傳照片的尺寸搜索排名優(yōu)化公司
  • 網(wǎng)站開發(fā)框架圖欽州seo
  • 哪有做網(wǎng)站的 優(yōu)幫云seo超級外鏈發(fā)布
  • 西寧網(wǎng)站制作哪家公司好網(wǎng)站設(shè)計(jì)模板網(wǎng)站
  • 韶關(guān)網(wǎng)站建設(shè)廣告聯(lián)盟平臺掛機(jī)賺錢
  • 采購網(wǎng)站平臺遼陽網(wǎng)站seo
  • 建站行業(yè)現(xiàn)狀探討今日頭條權(quán)重查詢
  • 網(wǎng)站搭建費(fèi)用明細(xì)樂天seo培訓(xùn)
  • 蒙山縣網(wǎng)站建設(shè)鞍山seo外包
  • 個(gè)人證書查詢網(wǎng)全國聯(lián)網(wǎng)南寧seo優(yōu)化公司排名
  • 網(wǎng)站設(shè)計(jì)主要包含3個(gè)方面市場調(diào)研報(bào)告萬能模板
  • 如何做網(wǎng)站拉動條黑帽seo是什么
  • 網(wǎng)頁設(shè)計(jì)怎樣設(shè)置圖片大小公司seo排名優(yōu)化
  • 網(wǎng)站建設(shè)開發(fā)軟件有哪些關(guān)鍵詞推廣優(yōu)化排名品牌
  • asp 網(wǎng)站開發(fā) 軟件怎么做網(wǎng)絡(luò)平臺
  • 如何做好網(wǎng)站管理工作深圳網(wǎng)絡(luò)推廣代運(yùn)營
  • 即墨城鄉(xiāng)建設(shè)局網(wǎng)站2345瀏覽器官網(wǎng)