日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【进程通信】Signal信号

發(fā)布時間:2025/4/5 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【进程通信】Signal信号 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

信號(signal)

??軟中斷信號(signal,又簡稱為信號)是Linux下用來在進程間傳遞消息的方式之一,也是進程間唯一的異步通信方式。從命名中可以看出信號的實質(zhì)很像中斷。進程間可以通過調(diào)用kill庫函數(shù)發(fā)送軟中斷信號,Linux內(nèi)核也可能給進程發(fā)送信號,用以告知該進程發(fā)生了某個異步事件。

??注意,信號只用來告知進程發(fā)生了某個異步事件,并不用來傳遞數(shù)據(jù)。進程收到信號后會有三種處理方式:

  • 忽略,不做任何處理
  • 執(zhí)行預(yù)先設(shè)置的處理函數(shù)(就像中斷服務(wù)程序一樣)
  • 采用系統(tǒng)的默認操作,大部分是終止進程

?

信號的來源

  • 用戶

    一般是鍵盤的輸入會作為信號發(fā)送給進程,比如:Ctrl + C 發(fā)送SIGINT信號給進程,默認動作為終止進程;Ctrl + \ 發(fā)送SIGQUIT信號給進程,默認動作為終止進程并進行內(nèi)核映像轉(zhuǎn)儲(core dump)

  • 內(nèi)核

    當進程執(zhí)行出錯時,內(nèi)核給進程發(fā)送一個對應(yīng)信號,例如:非法內(nèi)存引用、浮點數(shù)溢出、執(zhí)行非法指令

  • 進程

    C++的kill庫函數(shù)用于進程間發(fā)送信號

  • ?

    信號的類型

    信號名信號值默認處理動作發(fā)出信號的原因
    SIGINT2終止進程鍵盤中斷Ctrl+c
    SIGQUIT3終止進程并進行內(nèi)核映像轉(zhuǎn)儲鍵盤的退出鍵被按下
    SIGKILL9終止進程,并且不能被捕獲、忽略采用kill -9 進程編號 強制殺死程序。
    SIGSEGV11終止進程并進行內(nèi)核映像轉(zhuǎn)儲無效的內(nèi)存引用
    SIGTERM15終止進程采用“kill 進程編號”或“killall 程序名”通知程序。
    SIGCHLD20,17,18忽略此信號子進程結(jié)束信號

    PS:

    ? 內(nèi)核映像轉(zhuǎn)儲(core dump),內(nèi)核映像轉(zhuǎn)儲是指將進程數(shù)據(jù)在內(nèi)存的映像和進程在內(nèi)核結(jié)構(gòu)中的部分內(nèi)容以一定格式轉(zhuǎn)儲到文件系統(tǒng),并且進程退出執(zhí)行,這樣做的好處是為程序員 提供了方便,使得他們可以得到進程當時執(zhí)行時的數(shù)據(jù)值,允許他們確定轉(zhuǎn)儲的原因,并且可以調(diào)試他們的程序。

    ?

    信號的捕獲處理

    #include <signal.h> sighandler_t signal(int signum, sighandler_t handler) //signum 表示信號的編號//handler 表示信號的處理方式,有三種:1. SIG_IGN:忽略改信號,不作為2. SIG_DFL:恢復該信號的默認處理方法3. 自定義處理函數(shù),注意函數(shù)參數(shù)為 (int signum)

    ?

    信號的發(fā)送

    int kill(pid_t pid, int sig) //pid 目標進程號,有三種情況:1. pid>0 將信號sig傳給號為pid的進程2. pid=0 將信號sig傳給同進程組的所有進程(包括自己),常用于父進程給子進程發(fā)送信號3. pid=-1 將信號廣播到系統(tǒng)內(nèi)所有進程,例如系統(tǒng)關(guān)機時向所有登錄窗口廣播關(guān)機信息//sig 被發(fā)送的信號編號

    ?

    信號的應(yīng)用

    屏蔽信號

    ??通常為了程序不被干擾,程序開頭通常會屏蔽所有信號,然后再用signal函數(shù)對關(guān)心的信號設(shè)置相應(yīng)的處理方式。

    for(int i=0; i<100; i++) signal(i, SIG_IGN);

    ?

    搞點好玩的

    ??改變信號 SIGINT 和 SIGTERM的捕獲處理,設(shè)計一個 ctrl+C 和 kill 都殺不掉的進程:

    #include <stdio.h> #include <stdlib.h> #include <signal.h>void func(int sig) {if (sig == SIGINT)printf("\b\b殺不死,哈哈哈哈。\n");else if (sig == SIGTERM)printf("還是殺不死,哈哈哈哈。\n"); }int main() {for (int ii = 0; ii < 100; ii++)signal(ii, SIG_IGN); // 屏蔽全部的信號signal(SIGINT, func);signal(SIGTERM, func); // 設(shè)置SIGINT和SIGTERM的處理函數(shù)while (1); }

    效果:

    使用Ctrl+C 嘗試關(guān)掉進程:

    用 ps -ef | grep signal 找到其進程號,嘗試用 kill 直接干掉:

    可以看見,kill + 進程號 或 killall + 進程名 對它都無效,那改怎么殺死這個進程呢?如圖,用 kill -9 進程號:

    因為kill -9 進程號 發(fā)送的信號是 SIGKILL,這個信號無法被捕獲或忽略,能夠快準狠殺掉進程

    ?

    使系統(tǒng)休眠

    這個是我嘗試用 kill() 函數(shù)向系統(tǒng)所有進程發(fā)送 SIGKILL 信號后發(fā)現(xiàn)的,當然是在虛擬機上,我可不敢在主機上這樣搞:

    #include <stdio.h> #include <signal.h>int main() {kill(-1, SIGKILL); }

    效果是虛擬機進入休眠,輸入密碼后能再進入,原以為會直接關(guān)機呢

    總結(jié)

    以上是生活随笔為你收集整理的【进程通信】Signal信号的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。