chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

一篇文章徹底搞定信號!

Linux愛好者 ? 來源:CSDN技術社區(qū) ? 作者:903419 ? 2022-12-06 14:26 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.信號是什么?

信號其實就是一個軟件中斷。

例:

輸入命令,在Shell下啟動一個前臺進程。

用戶按下Ctrl-C,鍵盤輸入產(chǎn)生一個硬件中斷。

如果CPU當前正在執(zhí)行這個進程的代碼,則該進程的用戶空間代碼暫停執(zhí)行, CPU從用戶態(tài)切換到內(nèi)核態(tài)處理硬件中斷。

終端驅(qū)動程序?qū)trl-C解釋成一個SIGINT信號,記在該進程的PCB中(也可以說發(fā)送了一個SIGINT信號給該進程)。

當某個時刻要從內(nèi)核返回到該進程的用戶空間代碼繼續(xù)執(zhí)行之前,首先處理PCB中記錄的信號,發(fā)現(xiàn)有一個SIGINT信號待處理,而這個信號的默認處理動作是終止進程,所以直接終止進程而不再返回它的用戶空間代碼執(zhí)行。

在這個例子中,由ctrl+c產(chǎn)生的硬件中斷就是一個信號。Ctrl+C產(chǎn)生的信號只能發(fā)送給前臺進程,命令后加&就可放到后臺運行。Shell可同時運行一個前臺進程和任意多個后臺進程,只有前臺進程才能接受到像CTRL+C這種控制鍵產(chǎn)生的信號。

2.信號的種類

使用命令查看:

kill-l

非可靠信號:1~31號信號,信號可能會丟失可靠信號:34~64號信號,信號不可能丟失

bf80fb7a-7387-11ed-8abf-dac502259ad0.png

SIGHUP:1號信號,Hangup detected on controlling terminal or death of controlling process(在控制終端上掛起信號,或讓進程結束),ation:term

SIGINT:2號信號,Interrupt from keyboard(鍵盤輸入中斷,ctrl + c ),action:term

SIGQUIT:3號信號,Quit from keyboard(鍵盤輸入退出,ctrl+ | ),action:core,產(chǎn)生core dump文件

SIGABRT:6號信號,Abort signal from abort(3)(非正常終止,double free),action:core

SIGKILL:9號信號,Kill signal(殺死進程信號),action:term,該信號不能被阻塞、忽略、自定義處理

SIGSEGV:11號信號,Invalid memory reference(無效的內(nèi)存引用,解引用空指針、內(nèi)存越界訪問),action:core

SIGPIPE:13號信號,Broken pipe: write to pipe with no readers(管道中止: 寫入無人讀取的管道,會導致管道破裂),action:term

SIGCHLD:17號信號,Child stopped or terminated(子進程發(fā)送給父進程的信號,但該信號為忽略處理的)

SIGSTOP:19號信號,Stop process(停止進程),action:stop

SIGTSTP:20號信號,Stop typed at terminal(終端上發(fā)出的停止信號,ctrl + z),action:stop

具體的信號采取的動作和詳細信息可查看:man 7 signal

3.信號的產(chǎn)生

3.1硬件產(chǎn)生

硬件產(chǎn)生即通過終端按鍵產(chǎn)生的信號:

ctrl + c:SIGINT(2),發(fā)送給前臺進程,& 進程放到后臺運行,fg 把剛剛放到后臺的進程,再放到前臺來運行

ctrl + z:SIGTSTP(20),一般不用,除非有特定場景

ctrl + | :SIGQUIT(3),產(chǎn)生core dump文件

產(chǎn)生core dump文件的條件:

當前OS一定不要限制coredump文件的大小,ulimit-a
磁盤空間要足夠
如何產(chǎn)生:
3.1解引用空指針,收到11號信號,產(chǎn)生coredump文件
3.2內(nèi)存訪問越界,程序一旦崩潰,就會收到11號信號,也就會產(chǎn)生coredump文件
3.3 double free,收到6號信號,并產(chǎn)生core dump。
3.4free(NULL),不會崩潰

3.2軟件產(chǎn)生

軟件產(chǎn)生即調(diào)用系統(tǒng)函數(shù)向進程發(fā)信號

kill函數(shù)

#include
#include
intkill(pid_tpid,intsig);
參數(shù)解釋:
pid:進程號
sig:要發(fā)送的信號值
返回值:成功返回0,失敗返回-1,并設置錯誤

kill命令:kill -[信號] pid,

abort:void abort(void);,收到6號信號,誰調(diào)用該函數(shù),誰就收到信號

alarm:unsigned int alarm(unsigned int seconds);,收到14號信號,告訴內(nèi)核在seconds秒后給進程發(fā)送SIGALRM信號,該信號默認處理動作為終止當前進程。

4.信號的注冊

信號注冊又分為可靠信號的注冊和非可靠信號的注冊。信號注冊實際上是一個位圖和一個sigqueue隊列。bfbef272-7387-11ed-8abf-dac502259ad0.png

4.1非可靠信號的注冊

當進程收到非可靠信號時:

將非可靠信號對應的比特位置為1

添加sigqueue節(jié)點到sigqueue隊列當中,但是,在添加sigqueue節(jié)點的時候,隊列當中已然有了該信號的sigqueue節(jié)點,則不添加

4.2可靠信號的注冊

當進程所受到可靠信號時:

在sig位圖中更改信號對應的比特位為1不論之前sigqueue隊列中是否存在該信號的sigqueue節(jié)點,都再次添加sigqueue節(jié)點到sigqueue隊列當中去

5.信號的注銷

5.1非可靠信號的注銷

信號對應的比特位從1置為0將該信號的sigqueue節(jié)點從sigqueue隊列當中進行出隊操作

5.2可靠信號的注銷

將該信號的sigqueue節(jié)點從sigqueue隊列當中進行出隊操作需要判斷sigqueue隊列當中是否還有相同的sigqueue節(jié)點:①沒有了:信號比特位從1置為0②還有:不會更改sig位圖中的比特位

6.信號阻塞

6.1信號是怎樣阻塞的?

bfdf9c20-7387-11ed-8abf-dac502259ad0.png

信號的阻塞,并不會干擾信號的注冊。信號能注冊,但不能被立即處理,將block位圖中對應的信號比特位置為1,表示阻塞該信號進程收到該信號,還是一如既往的注冊當進程進入到內(nèi)核空間,準備返回用戶空間的時候,調(diào)用do_signal函數(shù),就不會立即去處理該信號了當該信號不被阻塞后,就可以進行處理了

6.2sigprocmask

函數(shù)原型:int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);參數(shù)解釋:

how,該做什么樣的操作
SIG_BLOCK:設置信號為阻塞
SIG_UNBLOCK:解除信號阻塞
SIG_SETMASK:替換阻塞位圖
set:用來設置阻塞位圖
SIG_BLOCK:設置某個信號為阻塞,block(new)=block(old)|set
SIG_UNBLOCK:解除某個信號阻塞,block(new)=block(old)&(~set)
SIG_SETMASK:替換阻塞位圖,block(new)=set
oldset:原來的阻塞位圖

例:下述例子,信號全部被阻塞,采用kill -9,將該進程結束掉

#include
#include
#include


voidsigncallback(intsignumber)
{
printf("changethesignal%d
",signumber);
}

intmain()
{
sigset_tset;
sigset_toldset;
sigfillset(&set);//所有比特位全置為1,則信號全部會被阻塞
sigprocmask(SIG_BLOCK,&set,&oldset);
while(1)
{
sleep(1);
}

return0;
}

結果:此時發(fā)送信號是不會有作用的,采用kill -9強殺掉

bffb4074-7387-11ed-8abf-dac502259ad0.png

7.信號未決

7.1 未決概念

實際執(zhí)行信號的處理動作稱為信號遞達(Delivery),信號從產(chǎn)生到遞達之間的狀態(tài),稱為信號未決(Pending)。進程可以選擇阻塞(Block)某個信號。被阻塞的信號產(chǎn)生時將保持在未決狀態(tài),直到進程解除對此信號的阻塞,才執(zhí)行遞達的動作。注意,阻塞和忽略是不同的,只要信號被阻塞就不會遞達,而忽略是、在遞達之后可選的一種處理動作。

7.2 sigpending

函數(shù)原型:int sigpending(sigset_t *set);讀取當前進程的未決信號集,通過set參數(shù)傳出。調(diào)用成功返回0,出錯返回-1.

例:

#include
#include
#include

voidsignalcallback(intsignumber)
{
printf("changsignumber%d
",signumber);
}
voidprintsigset(sigset_t*set)
{
inti=0;
for(;i

結果:c0119a22-7387-11ed-8abf-dac502259ad0.png

8.信號的處理方式

c044a598-7387-11ed-8abf-dac502259ad0.png

每個信號都有兩個標志位分別表示阻塞和未決,還有一個函數(shù)指針表示處理動作。

在上述例子中:

SIGHUP信號未阻塞也未產(chǎn)生過,當它遞達時執(zhí)行默認處理動作。

SIGINT信號產(chǎn)生過,但正在被阻塞,所以暫時不能遞達。雖然它的處理動作是忽略,但在沒有解除阻塞之前不能忽略這個信號,因為進程仍有機會改變處理動作之后再解除阻塞。

SIGQUIT信號未產(chǎn)生過,一旦產(chǎn)生SIGQUIT信號將被阻塞,它的處理動作是用戶自定義函數(shù)sighandler。

8.1signal函數(shù)

該函數(shù)可以更改信號的處理動作。

typedefvoid(*sighandler_t)(int);
sighandler_tsignal(intsignum,sighandler_thandler);
參數(shù)解釋:

signum:更改的信號值
handler:函數(shù)指針,要更改的動作是什么

實際上,該函數(shù)內(nèi)部也調(diào)用了sigaction函數(shù)。

8.2sigaction函數(shù)

讀取和修改與指定信號相關聯(lián)的處理動作。

intsigaction(intsignum,conststructsigaction*act,structsigaction*oldact);

參數(shù)解釋:

signum:待更改的信號值

struct sigaction結構體:

void(*sa_handler)(int);//函數(shù)指針,保存了內(nèi)核對信號的處理方式
void(*sa_sigaction)(int,siginfo_t*,void*);//
sigset_tsa_mask;//保存的是當進程在處理信號的時候,收到的信號
intsa_flags;//SA_SIGINFO,OS在處理信號的時候,調(diào)用的就是sa_sigaction函數(shù)指針當中
//保存的值0,在處理信號的時候,調(diào)用sa_handler保存的函數(shù)
void(*sa_restorer)(void);

例:

#include
#include
#include

voidsigncallback(intsignumber)
{
printf("changesignumber%d
",signumber);
}


intmain()
{
structsigactionact;//act為入?yún)?sigemptyset(&act.sa_mask);
act.sa_flags=0;
act.sa_handler=signcallback;

structsigactionoldact;//oldact為出參
sigaction(3,&act,&oldact);
while(1)
{
sleep(1);
}
return0;
}

結果:c06ab7f6-7387-11ed-8abf-dac502259ad0.png

8.3 自定義信號處理的流程

c082b806-7387-11ed-8abf-dac502259ad0.png

task_struct結構體中有一個struct sighand_struct結構體。

struct sighand_struct結構體有一個struct k_sigaction action[_NSIG]結構體數(shù)組。

該數(shù)組中,其中的_sighandler_t sa_handler保存的是信號的處理方式,通過改變其指向,可以實現(xiàn)我們對自定義信號的處理。

9.信號的捕捉

9.1信號捕捉的條件

如果信號的處理動作是用戶自定義函數(shù),在信號遞達時就調(diào)用這個函數(shù),這就稱為信號捕捉。

9.2信號捕捉流程

c097d182-7387-11ed-8abf-dac502259ad0.png

內(nèi)核態(tài)返回用戶態(tài)會調(diào)用do_signal函數(shù),兩種情況:

無信號:sys_return函數(shù),返回用戶態(tài)

有信號:先處理信號,信號返回,再調(diào)用do_signal函數(shù)例:

程序注冊了SIGQUIT信號的處理函數(shù)sighandler。

當前正在執(zhí)行main函數(shù),這時發(fā)生中斷或異常切換到內(nèi)核態(tài)。

在中斷處理完畢后要返回用戶態(tài)的main函數(shù)之前檢查到有信號SIGQUIT遞達。

內(nèi)核決定返回用戶態(tài)后不是恢復main函數(shù)的上下文繼續(xù)執(zhí)行,而是執(zhí)行sighandler函數(shù), sighandler和main函數(shù)使用不同的堆??臻g,它們之間不存在調(diào)用和被調(diào)用的關系,是兩個獨立的控制流程。

sighandler函數(shù)返回后自動執(zhí)行特殊的系統(tǒng)調(diào)用sigreturn再次進入內(nèi)核態(tài)。

如果沒有新的信號要遞達,這次再返回用戶態(tài)就是恢復main函數(shù)的上下文繼續(xù)執(zhí)行了。

10.常用信號集操作函數(shù)

intsigemptyset(sigset_t*set);://將比特位圖全置為0

intsigfillset(sigset_t*set);//將比特位圖全置為1

intsigaddset(sigset_t*set,intsignum);//將該set位圖,多少號信號置為1

intsigdelset(sigset_t*set,intsignum);//將該set位圖,多少號信號置為0

intsigismember(constsigset_t*set,intsignum);//信號signum是否是set位圖中的信號

11.SIGCHLD信號

該信號是子進程在結束是發(fā)送給父進程的信號,但是該信號的處理方式是默認處理的。父進程對子進程發(fā)送過來的SIGCHLD信號進行了忽略處理,就會導致子進程成為僵尸進程。

可以自定義該信號的處理方式:

#include
#include
#include
#include
#include
#include

voidsigncallback(intsignumber)
{
printf("changesignal%d
",signumber);
wait(NULL);
}

intmain()
{
signal(17,signcallback);
pid_tpid=fork();
if(pid

指令查看后臺:ps aux | grep ./fork

c0b0f310-7387-11ed-8abf-dac502259ad0.png

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    11279

    瀏覽量

    225016
  • 信號
    +關注

    關注

    12

    文章

    2914

    瀏覽量

    80142
  • 中斷
    +關注

    關注

    5

    文章

    917

    瀏覽量

    43761

原文標題:一篇文章徹底搞定信號!

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    全面認識MOS管,文章就夠了

    今天勢必要來文章,徹底掌握mos管!
    的頭像 發(fā)表于 06-13 10:37 ?2.5w次閱讀
    全面認識MOS管,<b class='flag-5'>一</b><b class='flag-5'>篇</b>文章就夠了

    徹底掌握MOS管

    基礎知識中 MOS 部分遲遲未整理,實際分享的電路中大部分常用電路都用到了MOS管, 今天勢必要來文章,徹底掌握mos管!
    發(fā)表于 07-05 11:56 ?3.3w次閱讀

    文章徹底搞定Linux信號!

    輸入命令,在 Shell 下啟動個前臺進程。
    發(fā)表于 11-21 11:26 ?583次閱讀

    徹底搞定指針

    本帖最后由 zgzzlt 于 2012-8-16 13:43 編輯 徹底搞定指針
    發(fā)表于 08-07 14:00

    徹底搞定C指針

    本帖最后由 發(fā)燒友之麒麟 于 2014-10-6 09:17 編輯 徹底搞定C指針教程,個人覺得寫得很好,希望對大家有幫助[attach]214619[/attach下面是個更深入理解C指針
    發(fā)表于 09-30 13:47

    如何搞定PCB設計的差分信號

    來源:互聯(lián)網(wǎng)在高速PCB設計中,差分信號的應用越來越廣泛,這主要原因是和普通的單端信號走線相比,差分信號具有抗干擾能力強、能有效抑制EMI、時序定位精確的優(yōu)勢。作為名(準)PCB設計
    發(fā)表于 10-23 08:36

    徹底搞定電路設計中的接地問題

    徹底搞定電路設計中的接地問題
    發(fā)表于 06-08 06:53

    【178頁完整版】輕松搞定C語言(提高)?。?/a>

    【178頁完整版】輕松搞定C語言(提高)?。⌒枰暾娴呐笥芽梢韵螺d附件保存哦~
    發(fā)表于 08-16 10:58

    輕松搞定C語言(提高)

    太大,上傳不了附件,以下是網(wǎng)盤鏈接:輕松搞定C語言(提高)鏈接:https://pan.baidu.com/s/1epKmrHjVZddkOiRugTSgXQ 提取碼:cq6c
    發(fā)表于 09-14 17:29

    徹底搞定C指針_姚云飛

    徹底搞定C指針》是互聯(lián)網(wǎng)上下載次數(shù)最多的針對C指針問題的中文資源之。現(xiàn)在,經(jīng)由修訂者的重新修訂、編輯與排版,本書的《完全版修訂增補版》全新登場。新版本中的技術用
    發(fā)表于 02-02 10:58 ?0次下載
    <b class='flag-5'>徹底</b><b class='flag-5'>搞定</b>C指針_姚云飛

    徹底搞定C指針

    徹底搞定C指針。
    發(fā)表于 03-17 09:59 ?1次下載

    徹底搞定C語言指針詳解完整版

    徹底搞定C語言指針詳解完整版。
    發(fā)表于 05-10 17:04 ?0次下載

    幾招搞定iPhone手機WiFi信號不穩(wěn)定

    有的時候,我們會發(fā)現(xiàn)我們的iPhone WiFi信號總是不滿格,用起來還很卡。對此許多果粉都束手無策,其實只要簡單幾招,就可以搞定這個問題。
    發(fā)表于 08-22 18:22 ?10.2w次閱讀

    多軸伺服,搞定

    多軸伺服,搞定
    的頭像 發(fā)表于 10-19 17:54 ?1323次閱讀
    多軸伺服,<b class='flag-5'>一</b>芯<b class='flag-5'>搞定</b>

    難搞的工業(yè)信號調(diào)節(jié),零漂移運算放大器是如何搞定的?

    難搞的工業(yè)信號調(diào)節(jié),零漂移運算放大器是如何搞定的?
    的頭像 發(fā)表于 12-06 16:59 ?1207次閱讀
    難搞的工業(yè)<b class='flag-5'>信號</b>調(diào)節(jié),零漂移運算放大器是如何<b class='flag-5'>搞定</b>的?