常見信號介紹
| SIGINT | 2 | Ctrl+C時OS送給前臺行程組中每個行程 |
|---|---|---|
| SIGABRT | 6 | 呼叫abort函式,行程例外終止 |
| SIGPOLL SIGIO | 8 | 指示一個異步IO事件,在高級IO中提及 |
| SIGKILL | 9 | 殺死行程的終極辦法 |
| SIGSEGV | 11 | 無效存盤訪問時OS發出該信號 |
| SIGPIPE | 13 | 涉及管道和socket |
| SIGALARM | 14 | 涉及alarm函式的實作 |
| SIGTERM | 15 | kill命令發送的OS默認終止信號 |
| SIGCHLD | 17 | 子行程終止或停止時OS向其父行程發此信號 |
| SIGUSR1 SIGUSR2 | 10 12 | 用戶自定義信號,作用和意義由應用自己定義 |
函式API
void func(int sig)
{
printf("func for signal: %d.\n", sig);
}
signal(SIGINT, 這里是處理函式func);
因為用的引數是SIGINT,所以當我們ctrl + c時不會終止程式
signal的處理函式有三種
位置在/usr/include/i386-linux-gnu/bits/signum.h中
可以自己寫處理函式,也可以通過上面的宏來決定信號怎么處理
| 默認處理 | SIG_DFL |
|---|---|
| 忽略處理 | SIG_IGN |
| 捕獲處理 | SIG_ERR |
signal(SIGINT, 宏);
sigaction函式介紹
sigaction比signal好的一點:
sigaction可以一次得到設定新捕獲函式和獲取舊的捕獲函式
其實還可以單獨設定新的捕獲或者單獨只獲取舊的捕獲函式
而signal函式不能單獨獲取舊的捕獲函式而必須在設定新的捕獲函式的同時才獲取舊的捕獲函式
alarm和pause函式
alarm是內核以API形式提供的鬧鐘
void func(int sig)
{
if (sig == SIGALRM)
{
printf("alarm happened.\n");
}
}
signal(SIGALRM, func);
ret = alarm(5);
使用sigaction函式結合alarm
void func(int sig)
{
if (sig == SIGALRM)
{
printf("alarm happened.\n");
}
}
struct sigaction act = {0};
act.sa_handler = func;
sigaction(SIGALRM, &act, NULL);
ret = alarm(5);
注意:alarm的回傳值等于定時的時間-過去的時間
所以當回傳值不是零,再呼叫一次alarm后,上次的alarm會被取消
pause函式—內核掛起
pause函式的作用就是讓當前行程暫停運行,交出CPU給其他行程去執行,
| 當前行程進入pause狀態后當前行程會表現為“卡住、阻塞住”,要退出pause狀態當前行程需要被信號喚醒, |
|---|
使用alarm和pause結合signal來模擬sleep
| alarm函式能定義時間,但不能睡眠 |
|---|
| pause函式能夠睡眠,但是不能定義時間 |
結合一下
#include <stdio.h>
#include <unistd.h> // unix standand
#include <signal.h>
void func(int sig)
{
printf("cx_sleep: %d.\n", sig);
}
void cx_sleep(int second);
int main(int argc, char **argv)
{
cx_sleep(1);
printf("1 cx_sleep after.\n");
cx_sleep(2);
printf("2 cx_sleep after.\n");
cx_sleep(3);
printf("3 cx_sleep after.\n");
return 0;
}
void cx_sleep(int second)
{
int ret=-1;
signal(SIGALRM, func);
ret=alarm(second);
pause();
}

或是使用alarm和pause結合sigaction來模擬sleep
void func(int sig)
{
printf("cx_sleep: %d.\n", sig);
}
void mysleep(unsigned int seconds);
int main(void)
{
cx_sleep(1);
printf("1 cx_sleep after.\n");
cx_sleep(2);
printf("2 cx_sleep after.\n");
cx_sleep(3);
printf("3 cx_sleep after.\n");
return 0;
}
void mysleep(unsigned int seconds)
{
struct sigaction act = {0};
act.sa_handler = func;
sigaction(SIGALRM, &act, NULL);
alarm(seconds);
pause();
}
```執行效果相同
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/272018.html
標籤:其他
