進(jìn)程間通信(4)-信號(hào)

一、信號(hào)

1、信號(hào)通信

信號(hào)通信,其實(shí)就是內(nèi)核向用戶(hù)空間進(jìn)程發(fā)送信號(hào)。

  • 只有內(nèi)核才能發(fā)信號(hào),用戶(hù)空間進(jìn)程不能發(fā)送信號(hào)。
  • 信號(hào)已經(jīng)存在了,不需要進(jìn)行創(chuàng)建。

內(nèi)核空間有很多信號(hào)。

kill -l:查看內(nèi)核可以發(fā)送多少種信號(hào)
kill -9 pid:殺死某個(gè)進(jìn)程
每種信號(hào)的id號(hào) + 功能

2、信號(hào)通信的框架

  • 信號(hào)的發(fā)送(發(fā)送信號(hào)進(jìn)程):kill raise alarm
  • 信號(hào)的接收(接收信號(hào)進(jìn)程) : pause() sleep while(1)
  • 信號(hào)的處理(接收信號(hào)進(jìn)程) : signal

二、信號(hào)的發(fā)送

1、kill函數(shù)

kill函數(shù)
Q:kill函數(shù)是如何實(shí)現(xiàn)的?

#include "sys/types.h"
#include "signal.h"
#include "unistd.h"
#include "stdio.h"
#include "stdlib.h"

int main(int argc, char *argv[])
{
    int sig;
    int pid;
    if(argc < 3)
    {
        printf("please input param\n");
        return -1;
    }
    sig = atoi(argv[1]);  // atoi函數(shù):將字符串轉(zhuǎn)化為整數(shù)
    pid = atoi(argv[2]);
    printf("sig = %d, pid = %d\n", sig, pid);
    return 0;
}
說(shuō)明字符串轉(zhuǎn)化為整數(shù)是成功的

2、raise函數(shù)

發(fā)信號(hào)給自己,而沒(méi)有發(fā)送給其他進(jìn)程。
相當(dāng)于kill(getpid(), sig)

raise函數(shù)
#include "stdio.h"
#include "sys/types.h"
#include "signal.h"
#include "stdio.h"
#include "stdlib.h"

int main()
{
    printf("raise before\n"); // 該行會(huì)被打印
    raise(9); // 把本進(jìn)程殺死
    printf("raise after\n"); // 該行不會(huì)被打印
    return 0;
}
image.png

3、alarm函數(shù)

alarm : 發(fā)送鬧鐘信號(hào)的函數(shù)。

alarm 與 raise 函數(shù)的比較:
相同點(diǎn):讓內(nèi)核發(fā)送信號(hào)給當(dāng)前進(jìn)程。
不同點(diǎn):

  1. alarm 只會(huì)發(fā)送SIGALARM信號(hào)
  2. alarm 會(huì)讓內(nèi)核定時(shí)一段時(shí)間之后發(fā)送信號(hào), raise會(huì)讓內(nèi)核立刻發(fā)信號(hào)
alarm函數(shù)
#include "stdio.h"
#include "sys/types.h"
#include "signal.h"
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int i = 0;
    printf("alarm before\n");
    alarm(9); // 定時(shí)9s,讓內(nèi)核發(fā)送SIGALARM信號(hào)
    printf("alarm after\n");
    while(i < 20) // 運(yùn)行20s
    {
        i++;
        sleep(1);
        printf("process things, i = %d\n", i);
    }
    return 0;
}
運(yùn)行結(jié)果

4、信號(hào)及其含義

信號(hào)及其含義.png

三、信號(hào)的接收

1、sleep函數(shù)

睡眠一段時(shí)間

2、pause函數(shù)

一直處于睡眠狀態(tài)

pause函數(shù)
#include "sys/types.h"
#include "signal.h"
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int i = 0;
    printf("pause before\n");
    pause(); // 一直睡眠
    printf("pause after\n");
    while(i < 20) // 運(yùn)行20s
    {
        i++;
        sleep(1);
        printf("process things, i = %d\n", i);
    }
    return 0;
}
pause一直睡眠

while(1)


四、信號(hào)的處理

收到信號(hào)的進(jìn)程,應(yīng)該怎樣處理? 處理的方式:
(1) 進(jìn)程的默認(rèn)處理方式(內(nèi)核為用戶(hù)進(jìn)程設(shè)置的默認(rèn)處理方式)
A:忽略
B:終止進(jìn)程
C:暫停
(2) 自己的處理方式:
自己處理信號(hào)的方法告訴內(nèi)核,這樣你的進(jìn)程收到了這個(gè)信號(hào)就會(huì)采用你自己的處理方式。

1、signal函數(shù)

signal函數(shù)

signal 函數(shù)有2個(gè)參數(shù),第1個(gè)參數(shù)是一個(gè)整形變量(信號(hào)值),告訴內(nèi)核處理哪個(gè)信號(hào);第2個(gè)參數(shù)是一個(gè)函數(shù)指針,是我們自己寫(xiě)的處理函數(shù),告訴內(nèi)核怎樣處理信號(hào)。
這個(gè)函數(shù)的返回值是一個(gè)函數(shù)指針。

#include "stdio.h"
#include "sys/types.h"
#include "signal.h"
#include "stdio.h"
#include "stdlib.h"

void myfun(int signum)
{
    int i = 0;
    while(i < 10)
    {
        printf("process signal signum = %d\n", signum);
        sleep(1);
        i++;
    }
    return; // 返回main函數(shù)
}

int main()
{
    int i = 0;
    signal(14, myfun); // 14號(hào)信號(hào)是SIGALARM信號(hào)
    printf("alarm before\n");
    alarm(9); // 定時(shí)9s,讓內(nèi)核發(fā)送SIGALARM信號(hào)
    printf("alarm after\n");
    while(i < 20) // 運(yùn)行20s
    {
        i++;
        sleep(1);
        printf("process things, i = %d\n", i);
    }
    return 0;
}
運(yùn)行結(jié)果-截圖1
運(yùn)行結(jié)果-截圖2
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容