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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)

發(fā)布時(shí)間:2025/3/20 linux 26 豆豆

【視頻教程】Linux信號(hào)詳解(可靠信號(hào)、不可靠信號(hào)、阻塞信號(hào)、信號(hào)處理函數(shù))

【博文】Linux信號(hào)

文章目錄

    • 背景
    • 課程筆記
    • 一、如何讓程序在后臺(tái)運(yùn)行
      • 1、加“&”符號(hào)
        • 測(cè)試ky_ai_camera_engine_origin
      • 2、采用fork
      • 3、如何中止后臺(tái)運(yùn)行中程序
    • 二、signal信號(hào)
      • 1、信號(hào)的基本概念
        • 軟中斷測(cè)試
      • 2、信號(hào)的類型
      • 3、signal庫(kù)函數(shù)
        • signal第三個(gè)參數(shù)可以這么玩
      • 4、信號(hào)有什么用
      • 5、信號(hào)應(yīng)用示例
        • 示例(book257.cpp)
    • 三、發(fā)送信號(hào) (kill函數(shù))
    • 四、信號(hào)更多的知識(shí)(20220123繼續(xù))關(guān)于可靠信號(hào)與不可靠信號(hào)詳解
    • 五、信號(hào)處理函數(shù)被中斷(新信號(hào)會(huì)插隊(duì)舊信號(hào),同種信號(hào)不會(huì)插隊(duì))
    • 六、信號(hào)的阻塞(信號(hào)集概念)(讓信號(hào)集里的信號(hào)延遲到達(dá)【觸發(fā)】)(信號(hào)遞達(dá)Delivery、信號(hào)未決Pending)
    • 七、信號(hào)signal拓展,功能更強(qiáng)的sigaction(但貌似也不能附加自定義消息)

背景

在真實(shí)的項(xiàng)目中,后臺(tái)服務(wù)程序不受終端控制,常駐內(nèi)存中,沒有交互的界面。
周期性或通過事件喚醒的方式執(zhí)行任務(wù)。(周期性指的是程序自發(fā)的,比如間隔一段時(shí)間就跑到某個(gè)文件目錄中看一看有沒有文件,如果有就上傳到服務(wù)器;事件喚醒指的是其他進(jìn)程主動(dòng)去通知該進(jìn)程執(zhí)行某項(xiàng)任務(wù))

課程筆記

一、如何讓程序在后臺(tái)運(yùn)行

在之前的章節(jié)中,如果要運(yùn)行程序,在命令提示行下輸入程序名后回車,程序被執(zhí)行,然后等待程序運(yùn)行完成,在程序運(yùn)行的過程中,也可以用Ctrl+c中止它。

在實(shí)際開發(fā)中,我們需要讓程序在后臺(tái)運(yùn)行,沒有界面,沒有用戶輸入數(shù)據(jù),例如socket服務(wù)端程序book250。

如果想讓程序在后臺(tái)運(yùn)行,有兩種方法。

1、加“&”符號(hào)

如果想讓程序在后臺(tái)運(yùn)行,執(zhí)行程序的時(shí)候,命令的最后面加“&”符號(hào)。

如:./book250 &
程序就在后臺(tái)運(yùn)行了。

在后臺(tái)運(yùn)行的程序,用Ctrl+c無法中斷,并且就算終端退出了,程序仍在后臺(tái)運(yùn)行。
如果終端退出了,后臺(tái)運(yùn)行的程序?qū)⒂上到y(tǒng)托管。

在第一張圖中,book250的父進(jìn)程是12178,第二張圖中,book250的父進(jìn)程是1。
為了不影響接下來的學(xué)習(xí),用killall book250指令讓book250程序退出。

測(cè)試ky_ai_camera_engine_origin

運(yùn)行run.sh程序跑起來后,用ps -ef | grep xxx指令查看進(jìn)程,第二個(gè)數(shù)字是子進(jìn)程,第三個(gè)數(shù)字是父進(jìn)程,可以一步一步查看父進(jìn)程,但是一個(gè)父進(jìn)程可能有幾個(gè)子進(jìn)程,怎么查看父進(jìn)程的子進(jìn)程?(可以用ps --ppid 父進(jìn)程號(hào))

[root@RV1126_RV1109:/]# ps -ef | grep ky_ai_camera_engine root 1264 2648 0 20:46 pts/1 00:00:00 grep ky_ai_camera_engine root 3328 3327 99 20:41 pts/2 00:07:57 /userdata/kyai/ky_ai_camera_engine_origin -a /oem/etc/iqfiles -p /userdata/kyai/model/rv1109_rv1126/yolov5s_relu_rv1109_rv1126_out_opt.rknn -c /userdata/kyai/rtsp-nn.cfg -l /userdata/kyai/model/coco_80_labels_list.txt [root@RV1126_RV1109:/]# [root@RV1126_RV1109:/]# [root@RV1126_RV1109:/]# ps -ef | 3327 -sh: 3327: not found [root@RV1126_RV1109:/]# ps -ef | grep 3327 root 1508 2648 0 20:47 pts/1 00:00:00 grep 3327 root 3327 3229 0 20:41 pts/2 00:00:00 /bin/sh ./run.sh root 3328 3327 99 20:41 pts/2 00:09:10 /userdata/kyai/ky_ai_camera_engine_origin -a /oem/etc/iqfiles -p /userdata/kyai/model/rv1109_rv1126/yolov5s_relu_rv1109_rv1126_out_opt.rknn -c /userdata/kyai/rtsp-nn.cfg -l /userdata/kyai/model/coco_80_labels_list.txt [root@RV1126_RV1109:/]# [root@RV1126_RV1109:/]# [root@RV1126_RV1109:/]# [root@RV1126_RV1109:/]# ps -ef | grep 3229 root 1704 2648 0 20:48 pts/1 00:00:00 grep 3229 root 3229 3228 0 20:41 pts/2 00:00:00 -sh root 3327 3229 0 20:41 pts/2 00:00:00 /bin/sh ./run.sh [root@RV1126_RV1109:/]#

用killall能殺死進(jìn)程啊,我怎么之前試了半天殺不死??

[root@RV1126_RV1109:~]# killall ky_ai_camera_engine_origin [root@RV1126_RV1109:~]#

2、采用fork

另一種方法是采用fork,主程序執(zhí)行fork,生成一個(gè)子進(jìn)程,然后父進(jìn)程退出,留下子進(jìn)程繼續(xù)運(yùn)行,子進(jìn)程將由系統(tǒng)托管。

在book250的main函數(shù)后增加以下代碼:
(需要包含一些庫(kù),自己查詢)

if (fork()>0) return 0;

重新編譯后執(zhí)行book250,運(yùn)行效果如下:(父進(jìn)程號(hào)為1就表示在后臺(tái)運(yùn)行了)

上圖中,20752是fork后的子進(jìn)程,它的父進(jìn)程號(hào)是1,是系統(tǒng)進(jìn)程(親爹沒了,天地日月為父)。

3、如何中止后臺(tái)運(yùn)行中程序

問題來了,程序在后臺(tái)運(yùn)行了,離開了終端控制,用Ctrl+c上也無法中止,那怎么讓它停下來呢?暫時(shí)用一個(gè)笨方法,殺了它。

殺程序有兩個(gè)方法:

1)killall 程序名

killall book250

執(zhí)行效果

2)先用“ps -ef | grep 程序名”找到程序的進(jìn)程編號(hào),然后用“kill 進(jìn)程編號(hào)”。

執(zhí)行效果

老師:
程序在運(yùn)行的過程中,用ctrl+c、kill、killall中止其本質(zhì)是向程序發(fā)送信號(hào),程序?qū)@兩個(gè)信號(hào)的默認(rèn)行為是程序中止運(yùn)行。
在程序中,可以捕獲信號(hào),編寫信息處理函數(shù),即收到信號(hào)后執(zhí)行的代碼。
(意思就是我們可以在程序中寫捕獲信號(hào)的接口,然后其他調(diào)用者去調(diào)用它)

二、signal信號(hào)

signal信號(hào)是Linux編程中非常重要的部分,接下來將詳細(xì)介紹信號(hào)的基本概念、實(shí)現(xiàn)和使用,和與信號(hào)的幾個(gè)系統(tǒng)調(diào)用(庫(kù)函數(shù))。

signal信號(hào)是進(jìn)程之間相互傳遞消息的一種方法,信號(hào)全稱為軟中斷信號(hào),也有人稱作軟中斷,從它的命名可以看出,它的實(shí)質(zhì)和使用很像中斷。

1、信號(hào)的基本概念

軟中斷信號(hào)(signal,又簡(jiǎn)稱為信號(hào))用來通知進(jìn)程發(fā)生了事件。進(jìn)程之間可以通過調(diào)用kill庫(kù)函數(shù)發(fā)送軟中斷信號(hào)。Linux內(nèi)核也可能給進(jìn)程發(fā)送信號(hào),通知進(jìn)程發(fā)生了某個(gè)事件(例如內(nèi)存越界)。

注意,信號(hào)只是用來通知某進(jìn)程發(fā)生了什么事件,無法給進(jìn)程傳遞任何數(shù)據(jù),進(jìn)程對(duì)信號(hào)的處理方法有三種:

1)第一種方法是,忽略某個(gè)信號(hào),對(duì)該信號(hào)不做任何處理,就象未發(fā)生過一樣。

2)第二種是設(shè)置中斷的處理函數(shù),收到信號(hào)后,由該函數(shù)來處理。

3)第三種方法是,對(duì)該信號(hào)的處理采用系統(tǒng)的默認(rèn)操作,大部分的信號(hào)的默認(rèn)操作是終止進(jìn)程。

軟中斷測(cè)試

在ubuntu下測(cè)試,測(cè)試發(fā)現(xiàn),軟中斷觸發(fā)時(shí),睡眠sleep會(huì)立刻結(jié)束,但是我開了個(gè)for循環(huán),發(fā)現(xiàn)for循環(huán)不會(huì)立刻結(jié)束,幾乎不受影響

測(cè)試的時(shí)候還發(fā)現(xiàn)了這個(gè)問題。。為什么ubuntu64位下C語(yǔ)言for循環(huán)不能超過2147483647次?

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <signal.h>#include<time.h> #include<sys/time.h> #include<stdio.h>struct timeval tv;void EXIT(int sig) {gettimeofday(&tv,NULL);printf("exit開始計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);int count =0;//for(int i=0;i<2147483648;i++){ //nofor(int i=0;i<2147483647;i++){ //yes//count+=2; count+=0.1;}//printf("count:%d\n",count); printf("收到了信號(hào)%d\n",sig);gettimeofday(&tv,NULL);printf("exit結(jié)束計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);// 在這里添加釋放資源的代碼//exit(0); // 程序退出。 }int main(){for (int ii=0;ii<100;ii++) signal(ii,SIG_IGN); // 屏蔽全部的信號(hào)signal(SIGINT,EXIT); signal(SIGTERM,EXIT); // 設(shè)置SIGINT和SIGTERM的處理函數(shù)while (1){ // 一個(gè)死循環(huán)//printf("執(zhí)行了一次\n"); //sleep(5);//printf("執(zhí)行了二次\n"); //sleep(5);//printf("執(zhí)行了三次\n"); gettimeofday(&tv,NULL);printf("main開始計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);int count =0;//for(int i=0;i<2147483648;i++){ //nofor(int i=0;i<2147483647;i++){ //yes//count+=2; count+=0.1;}//printf("count:%d\n",count);gettimeofday(&tv,NULL);printf("main結(jié)束計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);} }

運(yùn)行結(jié)果:

[yg@ubuntu /arnold_test/20220113_TEST_signal]1$ ./a.out main開始計(jì)算, 秒:1642822914,毫秒:985 main結(jié)束計(jì)算, 秒:1642822927,毫秒:194 (main interval 13s) main開始計(jì)算, 秒:1642822927,毫秒:194 ^Cexit開始計(jì)算, 秒:1642822929,毫秒:176 收到了信號(hào)2 exit結(jié)束計(jì)算, 秒:1642822940,毫秒:864 (exit interval 11s) main結(jié)束計(jì)算, 秒:1642822950,毫秒:20 (main interval 23s) main開始計(jì)算, 秒:1642822950,毫秒:20 ^Cexit開始計(jì)算, 秒:1642822955,毫秒:593 ^C收到了信號(hào)2 exit結(jié)束計(jì)算, 秒:1642822967,毫秒:9 (exit interval 12s) exit開始計(jì)算, 秒:1642822967,毫秒:9 ^C^C^C^C收到了信號(hào)2 exit結(jié)束計(jì)算, 秒:1642822978,毫秒:658 (exit interval 11s) exit開始計(jì)算, 秒:1642822978,毫秒:658 收到了信號(hào)2 exit結(jié)束計(jì)算, 秒:1642822991,毫秒:54 (exit interval 13s) main結(jié)束計(jì)算, 秒:1642822996,毫秒:605 (main interval 46s)

結(jié)論:
當(dāng)接收到信號(hào)后,會(huì)將主進(jìn)程阻塞,去執(zhí)行信號(hào)處理函數(shù);在處理信號(hào)處理函數(shù)時(shí),還收到多個(gè)相同信號(hào),只按一個(gè)處理(為了增加可信度,我再在main函數(shù)里開個(gè)線程,測(cè)試一下)

我開多線程測(cè)試結(jié)論:
signal(SIGINT,EXIT); signal(SIGTERM,EXIT);這句代碼,只有它后面的的代碼才能生效,前面的代碼不會(huì)(在它后面開的線程也會(huì)被阻塞住) ;(貌似不能這么下定義,我測(cè)試發(fā)現(xiàn),如果main和test_thread一起跑的時(shí)候,按下ctrl+c,那么main就停了,只有test_thread和exit在跑,然后再按一下,test_thread就停了,只有exit在跑(無論signal(SIGINT,EXIT); signal(SIGTERM,EXIT);是放在線程前還是后))(感覺這個(gè)有個(gè)問題就是signal觸發(fā)的時(shí)候它會(huì)把主進(jìn)程給阻塞了,所以最好不要在signal處理函數(shù)里搞太多耗時(shí)的事情?)

附測(cè)試代碼:

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <signal.h>#include<time.h> #include<sys/time.h> #include<stdio.h>#include <pthread.h>#define loop_num 5000000static int g_num = 0;struct timeval tv;void EXIT(int sig) {printf("g_num:%d\n", g_num); gettimeofday(&tv,NULL);printf("exit開始計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);int count =0;for(int i=0;i<loop_num;i++){ count+=1;printf("exit_count:%d\n",count);}//sleep(10);printf("exit結(jié)束計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);g_num++;// 在這里添加釋放資源的代碼//exit(0); // 程序退出。 }static void *Test(void *arg) {while (1){gettimeofday(&tv,NULL);printf("test_thread開始計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);int count =0;//for(int i=0;i<2147483648;i++){ //nofor(int i=0;i<loop_num;i++){ //yes//count+=2; count+=1;printf("test_count:%d\n",count);}//printf("count:%d\n",count);gettimeofday(&tv,NULL);printf("test_thread結(jié)束計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);} }int main(){for (int ii=0;ii<100;ii++) signal(ii,SIG_IGN); // 屏蔽全部的信號(hào)signal(SIGINT,EXIT); signal(SIGTERM,EXIT); // 設(shè)置SIGINT和SIGTERM的處理函數(shù)pthread_t test_thread;pthread_create(&test_thread, NULL, Test, NULL);//signal(SIGINT,EXIT); signal(SIGTERM,EXIT); // 設(shè)置SIGINT和SIGTERM的處理函數(shù)while (1){ // 一個(gè)死循環(huán)//printf("執(zhí)行了一次\n"); //sleep(5);//printf("執(zhí)行了二次\n"); //sleep(5);//printf("執(zhí)行了三次\n"); gettimeofday(&tv,NULL);printf("main開始計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);int count =0;//for(int i=0;i<2147483648;i++){ //nofor(int i=0;i<loop_num;i++){ //yes//count+=2; count+=1;printf("main_count:%d\n",count);}gettimeofday(&tv,NULL);printf("main結(jié)束計(jì)算, 秒:%ld,毫秒:%ld\n", tv.tv_sec, tv.tv_usec/1000);}//signal(SIGINT,EXIT); signal(SIGTERM,EXIT); //前面while循環(huán)導(dǎo)致這句根本執(zhí)行不到 }

2、信號(hào)的類型

發(fā)出信號(hào)的原因很多,這里按發(fā)出信號(hào)的原因簡(jiǎn)單分類,以了解各種信號(hào):
(重點(diǎn)關(guān)注加粗的信號(hào)名,其他的信號(hào)老師開發(fā)也沒怎么用過。。。)

處理動(dòng)作一項(xiàng)中的字母含義如下

A 缺省的動(dòng)作是終止進(jìn)程。B 缺省的動(dòng)作是忽略此信號(hào),將該信號(hào)丟棄,不做處理。C 缺省的動(dòng)作是終止進(jìn)程并進(jìn)行內(nèi)核映像轉(zhuǎn)儲(chǔ)(core dump),內(nèi)核映像轉(zhuǎn)儲(chǔ)是指將進(jìn)程數(shù)據(jù)在內(nèi)存的映像和進(jìn)程在內(nèi)核結(jié)構(gòu)中的部分內(nèi)容以一定格式轉(zhuǎn)儲(chǔ)到文件系統(tǒng),并且進(jìn)程退出執(zhí)行,這樣做的好處是為程序員 提供了方便,使得他們可以得到進(jìn)程當(dāng)時(shí)執(zhí)行時(shí)的數(shù)據(jù)值,允許他們確定轉(zhuǎn)儲(chǔ)的原因,并且可以調(diào)試他們的程序。D 缺省的動(dòng)作是停止進(jìn)程,進(jìn)入停止?fàn)顩r以后還能重新進(jìn)行下去。E 信號(hào)不能被捕獲。F 信號(hào)不能被忽略。

3、signal庫(kù)函數(shù)

signal庫(kù)函數(shù)可以設(shè)置程序?qū)π盘?hào)的處理方式。

函數(shù)聲明:

sighandler_t signal(int signum, sighandler_t handler);

參數(shù)signum表示信號(hào)的編號(hào)。(就是個(gè)宏定義,可直接用對(duì)應(yīng)數(shù)字替代)

參數(shù)handler表示信號(hào)的處理方式,有三種情況:

1)SIG_IGN:忽略參數(shù)signum所指的信號(hào)。(用了這個(gè)參數(shù)后信號(hào)就相當(dāng)于完全無效了)

2)一個(gè)自定義的處理信號(hào)的函數(shù),信號(hào)的編號(hào)為這個(gè)自定義函數(shù)的參數(shù)。

3)SIG_DFL:恢復(fù)參數(shù)signum所指信號(hào)的處理方法為默認(rèn)值。

程序員不關(guān)心signal的返回值。

signal第三個(gè)參數(shù)可以這么玩

調(diào)用signal函數(shù)后,相當(dāng)于開啟了一個(gè)監(jiān)聽子進(jìn)程?同樣放在函數(shù)里調(diào)用也一樣,函數(shù)退出,監(jiān)聽也就結(jié)束。。?這樣我們可以在信號(hào)執(zhí)行默認(rèn)操作前后摻雜我們自己的操作

4、信號(hào)有什么用

服務(wù)程序運(yùn)行在后臺(tái),如果想讓中止它,強(qiáng)行殺掉不是個(gè)好辦法,因?yàn)槌绦虮粴⒌臅r(shí)候,程序突然死亡,沒有釋放資源,會(huì)影響系統(tǒng)的穩(wěn)定,用Ctrl+c中止與殺程序是相同的效果。

如果能向后臺(tái)程序發(fā)送一個(gè)信號(hào),后臺(tái)程序收到這個(gè)信號(hào)后,調(diào)用一個(gè)函數(shù),在函數(shù)中編寫釋放資源的代碼,程序就可以有計(jì)劃的退出,安全而體面。

例如:(退出時(shí)判斷文件有沒關(guān)閉,沒關(guān)閉就關(guān)閉掉)

信號(hào)還可以用于網(wǎng)絡(luò)服務(wù)程序抓包等,這是較復(fù)雜的應(yīng)用場(chǎng)景,暫時(shí)不介紹。

5、信號(hào)應(yīng)用示例

在實(shí)際開發(fā)中,在main函數(shù)開始的位置,程序員會(huì)先屏蔽掉全部的信號(hào)。

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

這么做的目的是不希望程序被干擾。然后,再設(shè)置程序員關(guān)心的信號(hào)的處理函數(shù)。

程序員關(guān)心的信號(hào)有三個(gè):SIGINT、SIGTERM和SIGKILL。

程序在運(yùn)行的進(jìn)程中,如果按Ctrl+c,將向程序發(fā)出SIGINT信號(hào),信號(hào)編號(hào)是2。

采用“kill 進(jìn)程編號(hào)”或“killall 程序名”向程序發(fā)出的是SIGTERM信號(hào),編號(hào)是15。

采用“kill -9 進(jìn)程編號(hào)”向程序發(fā)出的是SIGKILL信號(hào),編號(hào)是9,此信號(hào)不能被忽略,也無法捕獲,程序?qū)⑼蝗凰劳觥?/p>

所以,程序員只要設(shè)置SIGINT和SIGTERM兩個(gè)信號(hào)的處理函數(shù)就可以了,這兩個(gè)信號(hào)可以使用同一個(gè)處理函數(shù),函數(shù)的代碼是釋放資源。

示例(book257.cpp)

/** 程序名:book257.cpp,此程序用于演示用信號(hào)通知后臺(tái)服務(wù)程序退出。* 作者:C語(yǔ)言技術(shù)網(wǎng)(www.freecplus.net) 日期:20190525 */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <signal.h>void EXIT(int sig) {printf("收到了信號(hào)%d,程序退出。\n",sig);// 在這里添加釋放資源的代碼exit(0); // 程序退出。 }int main() {for (int ii=0;ii<100;ii++) signal(ii,SIG_IGN); // 屏蔽全部的信號(hào)signal(SIGINT,EXIT); signal(SIGTERM,EXIT); // 設(shè)置SIGINT和SIGTERM的處理函數(shù)while (1) // 一個(gè)死循環(huán){sleep(10);} }

運(yùn)行效果

不管是用Ctrl+c還是kill,程序都能體面的退出。

三、發(fā)送信號(hào) (kill函數(shù))

Linux操作系統(tǒng)提供了kill命令向程序發(fā)送信號(hào),C語(yǔ)言也提供了kill庫(kù)函數(shù),用于在程序中向其它進(jìn)程或者線程發(fā)送信號(hào)。

函數(shù)聲明:

int kill(pid_t pid, int sig);

kill函數(shù)將參數(shù)sig指定的信號(hào)給參數(shù)pid 指定的進(jìn)程。

參數(shù)pid 有幾種情況:

1)pid>0 將信號(hào)傳給進(jìn)程號(hào)為pid 的進(jìn)程。2)pid=0 將信號(hào)傳給和目前進(jìn)程【相同進(jìn)程組】的所有進(jìn)程,常用于父進(jìn)程給子進(jìn)程發(fā)送信號(hào),注意,發(fā)送信號(hào)者進(jìn)程也會(huì)收到自己發(fā)出的信號(hào)。3)pid=-1 將信號(hào)廣播傳送給系統(tǒng)內(nèi)所有的進(jìn)程,例如系統(tǒng)關(guān)機(jī)時(shí),會(huì)向所有的登錄窗口廣播關(guān)機(jī)信息。sig:準(zhǔn)備發(fā)送的信號(hào)代碼,假如其值為零則沒有任何信號(hào)送出,但是系統(tǒng)會(huì)執(zhí)行錯(cuò)誤檢查,通常會(huì)利用sig值為零來檢驗(yàn)?zāi)硞€(gè)進(jìn)程是否仍在運(yùn)行。返回值說明: 成功執(zhí)行時(shí),返回0;失敗返回-1,errno被設(shè)為以下的某個(gè)值。EINVAL:指定的信號(hào)碼無效(參數(shù) sig 不合法)。EPERM:權(quán)限不夠無法傳送信號(hào)給指定進(jìn)程。ESRCH:參數(shù) pid 所指定的進(jìn)程或進(jìn)程組不存在。

看到22:05,我先去看dbus進(jìn)程間通信了,ly讓研究那個(gè),貌似有點(diǎn)復(fù)雜
https://www.bilibili.com/video/BV145411a76x?p=2&spm_id_from=pageDriver

四、信號(hào)更多的知識(shí)(20220123繼續(xù))關(guān)于可靠信號(hào)與不可靠信號(hào)詳解

不可靠信號(hào)可能會(huì)存在信號(hào)丟失

示例:

用killall+信號(hào)值+進(jìn)程名給進(jìn)程發(fā)信號(hào)

發(fā)現(xiàn)用killall -15 book10發(fā)送多次時(shí),除第一次觸發(fā)了外,后面幾次信號(hào)都被合成為了一次

但如果用killall -34 book10發(fā)送多次時(shí),每次信號(hào)都能正常觸發(fā)(不會(huì)丟失信號(hào))

作者(吳哥)將這個(gè)信號(hào)值15稱為“不可靠信號(hào)”,將信號(hào)值34稱為“可靠信號(hào)”

五、信號(hào)處理函數(shù)被中斷(新信號(hào)會(huì)插隊(duì)舊信號(hào),同種信號(hào)不會(huì)插隊(duì))


示例:略

六、信號(hào)的阻塞(信號(hào)集概念)(讓信號(hào)集里的信號(hào)延遲到達(dá)【觸發(fā)】)(信號(hào)遞達(dá)Delivery、信號(hào)未決Pending)


另外:sigfillset()函數(shù),跟sigaddset()類似,但它是一次性將所有信號(hào)添加進(jìn)去,而sigaddset()只是單個(gè)信號(hào)值添加

從信號(hào)集set中sigdelset()刪除一個(gè)信號(hào)值

sigismember()判斷某個(gè)信號(hào)值在不在信號(hào)集set里面

sigprocmask()函數(shù)的參數(shù)(how的第三個(gè)SIG_SETMASK作者也不知道)

七、信號(hào)signal拓展,功能更強(qiáng)的sigaction(但貌似也不能附加自定義消息)

linux 信號(hào) sigaction(是signal的擴(kuò)展,在多線程應(yīng)用中替代了signal)

總結(jié)

以上是生活随笔為你收集整理的【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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