一、什么是信號?
信號就像是一個突然的電話鈴聲,它會打斷正在進行的程式并引起其注意,
在Linux系統中,信號是一種軟體中斷,它通常是異步發生的,可以用來通知行程某個事件已經發生,,每個信號都有一個唯一的編號,編號從1開始,行程可以通過注冊信號處理函式來處理信號,
二、信號的分類
Linux系統中的信號有兩類:標準信號和實時信號,
-
標準信號是傳統Unix系統中的信號,編號范圍從1到31,
-
實時信號是Linux獨有的信號,編號范圍從32到64,
三、信號的使用
1、注冊信號處理函式
在C語言中,可以使用signal函式來注冊信號處理函式,signal函式原型如下:
void (*signal(int signum, void (*handler)(int)))(int);
其中,signum引數表示要注冊的信號編號,handler引數表示信號處理函式,signal函式會回傳上一次注冊的信號處理函式的地址,
下面是一個簡單的例子,注冊SIGINT信號的處理函式:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void sigint_handler(int signo)
{
printf("Received SIGINT signal!\n");
exit(0);
}
int main()
{
if (signal(SIGINT, sigint_handler) == SIG_ERR) {
perror("signal");
exit(1);
}
while (1) {
printf("Hello World!\n");
sleep(1);
}
return 0;
}
在上面的例子中,我們首先定義了一個名為sigint_handler的函式,用于處理SIGINT信號,
在main函式中,我們使用signal函式注冊了SIGINT信號的處理函式,如果signal函式回傳的值是SIG_ERR,表示注冊信號處理函式失敗,
在回圈中,我們只是簡單地輸出Hello World!字串,并使用sleep函式暫停1秒鐘,以便觀察信號處理程序,
- 編譯并運行,列印如下
[wayne@wayne:~]./signal
Hello World!
Hello World!
Hello World!
2、發送信號
2.1 kill函式
在Linux系統中,可以使用kill函式向行程發送信號,kill函式原型如下:
int kill(pid_t pid, int sig);
其中,pid引數表示行程的PID號,sig引數表示要發送的信號編號,如果pid引數的值是0,表示將信號發送給與當前行程屬于同一個行程組的所有行程,
下面是一個例子,向指定行程發送SIGINT信號:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "Usage: %s <pid>\n", argv[0]);
exit(1);
}
pid_t pid = atoi(argv[1]);
if (kill(pid, SIGINT) == -1) {
perror("kill");
exit(1);
}
return 0;
}
在上面的例子中,我們首先檢查命令列引數,如果引數不足,就列印使用說明并退出程式,
然后我們將命令列引數轉換為行程PID號,并使用kill函式向該行程發送SIGINT信號,如果kill函式回傳-1,表示發送信號失敗,
- 編譯并運行,列印如下
[wayne@wayne:~] ps aux | grep signal
wayne 5902 0.0 0.0 2028 280 pts/25 S+ 19:04 0:00 ./signal
wayne 5904 0.0 0.0 6108 852 pts/24 S+ 19:04 0:00 grep --color=auto signal
[wayne@wayne:~] ./killsignal 5902
// 此時上面運行的signal行程會收到信號,列印如下資訊
Received SIGINT signal!
2.2 kill命令
我們也可以在shell中,用kill命令向行程發送信號,kill命令的語法如下:
kill [options] <pid>
其中,pid表示要發送信號的行程PID號,options是一些可選引數,例如,可以使用-9引數發送SIGKILL信號,
我們可以打開一個新的終端視窗,使用ps命令查看本文介紹的示例程式的PID號,然后使用kill命令向該行程發送SIGINT信號,示例如下:
$ ps aux | grep signal
wayne 5902 0.0 0.0 2028 280 pts/25 S+ 19:04 0:00 ./signal
wayne 5904 0.0 0.0 6108 852 pts/24 S+ 19:04 0:00 grep --color=auto signal
$ kill -2 5902
這里我們使用ps命令查找名為signal的行程的PID號為5902,然后使用kill命令向該行程發送SIGINT信號(信號編號為2),在執行kill命令之后,我們可以看到示例程式輸出了"Received SIGINT signal"這一行資訊,說明信號處理函式已經被正確呼叫了,
四、常用信號
Linux系統中常用的信號有很多,下面列出一些常用的信號及其含義:
| 信號編號 | 信號名稱 | 含義 |
|---|---|---|
| 1 | SIGHUP | 終端掛起或者控制行程結束 |
| 2 | SIGINT | 中斷信號,通常是CTRL-C |
| 3 | SIGQUIT | 終止信號,通常是CTRL-\ |
| 9 | SIGKILL | 強制終止行程 |
| 11 | SIGSEGV | 段錯誤 |
| 15 | SIGTERM | 終止信號,通常是kill命令發送的信號 |
| 18 | SIGCONT | 繼續執行被暫停的行程 |
| 19 | SIGSTOP | 暫停行程 |
| 20 | SIGTSTP | 終端掛起或者CTRL-Z |
五、小結
總的來說,Linux 信號是一種用于通知行程發生某個事件或錯誤的機制,可以用于處理例外情況、行程間通信等多種場景,
以上,如果覺得對你有幫助,點個贊再走吧,這樣@知微之見也有更新下去的動力!
也歡迎私信我,一起交流!
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/547057.html
標籤:Linux
上一篇:使用舊電腦玩Linux
下一篇:Linux之修改軟鏈接地址
