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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【进程通信】Signal信号

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

信號(signal)

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

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

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

?

信號的來源

  • 用戶

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

  • 內核

    當進程執行出錯時,內核給進程發送一個對應信號,例如:非法內存引用、浮點數溢出、執行非法指令

  • 進程

    C++的kill庫函數用于進程間發送信號

  • ?

    信號的類型

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

    PS:

    ? 內核映像轉儲(core dump),內核映像轉儲是指將進程數據在內存的映像和進程在內核結構中的部分內容以一定格式轉儲到文件系統,并且進程退出執行,這樣做的好處是為程序員 提供了方便,使得他們可以得到進程當時執行時的數據值,允許他們確定轉儲的原因,并且可以調試他們的程序。

    ?

    信號的捕獲處理

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

    ?

    信號的發送

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

    ?

    信號的應用

    屏蔽信號

    ??通常為了程序不被干擾,程序開頭通常會屏蔽所有信號,然后再用signal函數對關心的信號設置相應的處理方式。

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

    ?

    搞點好玩的

    ??改變信號 SIGINT 和 SIGTERM的捕獲處理,設計一個 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); // 設置SIGINT和SIGTERM的處理函數while (1); }

    效果:

    使用Ctrl+C 嘗試關掉進程:

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

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

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

    ?

    使系統休眠

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

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

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

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。