信號

kill -l  查看所有信號程序員

前32個  unix經典信號算法

後32個稱爲實時信號(自定義信號)shell

kill能夠致使一個進程被終止網絡

90%的信號,默認都使進程終止併發

 1.2 信號機制異步

信號的三大行爲和五種默認動做   函數

核心已轉儲  必定是Core  動做測試

    SIGHUP            1               Term         Hangup detected on controlling terminal or death of controlling process
         SIGINT              2               Term         Interrupt from keyboard
         SIGQUIT           3               Core          Quit from keyboard
         SIGILL               4               Core           Illegal Instruction
         SIGABRT           6               Core           Abort signal from abort(3)
         SIGFPE              8               Core           Floating point exception
         SIGKILL             9               Term          Kill signal
         SIGSEGV          11              Core          Invalid memory reference          (段錯誤核心已轉儲)
         SIGPIPE           13              Term         Broken pipe: write to pipe with no readers
         SIGALRM         14              Term          Timer signal from alarm(2)
         SIGTERM         15              Term          Termination signal
         SIGUSR1          30,10,16   Term         User-defined signal 1
         SIGUSR2          31,12,17   Term         User-defined signal 2
         SIGCHLD          20,17,18   Ign            Child stopped or terminated          子進程結束給父進程發送一個SIGCHILD
         SIGCONT         19,18,25    Cont         Continue if stopped
         SIGSTOP          17,19,23    Stop         Stop process
         SIGTSTP           18,20,24    Stop         Stop typed at tty              (ctrl+z)只能暫停終端前臺進程
         SIGTTIN           21,21,26    Stop          tty input for background process
         SIGTTOU          22,22,27    Stop         tty output for background processui

jobs  spa

喚醒進程:fg(喚醒到前臺運行) bg(喚醒到後臺運行)

 1.3 信號產生種類

 

kill(-1,9)   -1是指給全部進程發送信號    執行這句話後致使計算機重啓

sig爲0時,用於檢測,特定爲pid進程是否存在,如不存在,返回-1。

1.4 信號產生緣由

1) SIGHUP:當用戶退出shell時,由該shell啓動的全部進程將收到這個信號,默認動做爲終止進程
2)SIGINT:當用戶按下了<Ctrl+C>組合鍵時,用戶終端向正在運行中的由該終端啓動的程序發出此信號。默認動做爲終止里程。3)SIGQUIT:當用戶按<ctrl+\>組合鍵時產生該信號,用戶終端向正在運行中的由該終端啓動的程序發出些信號。默認動做爲終止進程。
4)SIGILL:CPU檢測到某進程執行了非法指令。默認動做爲終止進程併產生core文件
5)SIGTRAP:該信號由斷點指令或其餘trap指令產生。默認動做爲終止里程併產生core文件。
6 ) SIGABRT:調用abort函數時產生該信號。默認動做爲終止進程併產生core文件。
7)SIGBUS:非法訪問內存地址,包括內存對齊出錯,默認動做爲終止進程併產生core文件。
8)SIGFPE:在發生致命的運算錯誤時發出。不只包括浮點運算錯誤,還包括溢出及除數爲0等全部的算法錯誤。默認動做爲終止進程併產生core文件。
9)SIGKILL:無條件終止進程。本信號不能被忽略,處理和阻塞。默認動做爲終止進程。它向系統管理員提供了能夠殺死任何進程的方法。
10)SIGUSE1:用戶定義的信號。即程序員能夠在程序中定義並使用該信號。默認動做爲終止進程。
11)SIGSEGV:指示進程進行了無效內存訪問。默認動做爲終止進程併產生core文件。
12)SIGUSR2:這是另一個用戶自定義信號,程序員能夠在程序中定義並使用該信號。默認動做爲終止進程。1
13)SIGPIPE:Broken pipe向一個沒有讀端的管道寫數據。默認動做爲終止進程。
14) SIGALRM:定時器超時,超時的時間由系統調用alarm設置。默認動做爲終止進程。
15)SIGTERM:程序結束信號,與SIGKILL不一樣的是,該信號能夠被阻塞和終止。一般用來要示程序正常退出。執行shell命令Kill時,缺省產生這個信號。默認動做爲終止進程。
16)SIGCHLD:子進程結束時,父進程會收到這個信號。默認動做爲忽略這個信號。
17)SIGCONT:中止進程的執行。信號不能被忽略,處理和阻塞。默認動做爲終止進程。
18)SIGTTIN:後臺進程讀終端控制檯。默認動做爲暫停進程。
19)SIGTSTP:中止進程的運行。按下<ctrl+z>組合鍵時發出這個信號。默認動做爲暫停進程。
21)SIGTTOU:該信號相似於SIGTTIN,在後臺進程要向終端輸出數據時發生。默認動做爲暫停進程。
22)SIGURG:套接字上有緊急數據時,向當前正在運行的進程發出些信號,報告有緊急數據到達。如網絡帶外數據到達,默認動做爲忽略該信號。
23)SIGXFSZ:進程執行時間超過了分配給該進程的CPU時間,系統產生該信號併發送給該進程。默認動做爲終止進程。
24)SIGXFSZ:超過文件的最大長度設置。默認動做爲終止進程。
25)SIGVTALRM:虛擬時鐘超時時產生該信號。相似於SIGALRM,可是該信號只計算該進程佔用CPU的使用時間。默認動做爲終止進程。
26)SGIPROF:相似於SIGVTALRM,它不公包括該進程佔用CPU時間還包括執行系統調用時間。默認動做爲終止進程。
27)SIGWINCH:窗口變化大小時發出。默認動做爲忽略該信號。
28)SIGIO:此信號向進程指示發出了一個異步IO事件。默認動做爲忽略。
29)SIGPWR:關機。默認動做爲終止進程。
30)SIGSYS:無效的系統調用。默認動做爲終止進程併產生core文件。
31)SIGRTMIN~(64)SIGRTMAX:LINUX的實時信號,它們沒有固定的含義(能夠由用戶自定義)。全部的實時信號的默認動做都爲終止進程。

 1.4 信號集處理函數
sigset_t爲信號集,可sizeof(sigset_t)察看
int sigemptyset(sigset_t *set)
int sigfillset(sigset_t *set)
int sigaddset(sigset_t *set, int signo)
int sigdelset(sigset_t *set, int signo)
int sigismember(const sigset_t *set, int signo)

unix經典信號不支持排隊(最多有一個)

例:利用捕捉函數測試,當咱們同時按不少次ctrl + c 時,只執行兩次

當第一個信號a(編號爲2)發來時,經過未決信號集,未決信號集置1,而後經過阻塞信號集,到達Handler,未決信號集置0,執行函數,在執行過程當中,系統將阻塞信號集的2號信號置1,此時,還有新的信號b(2)經過未決信號集,而後未決信號集置1 ,但此時,阻塞信號集2號信號也爲1,因此信號b就在未決信號和阻塞信號集之間,其他到來的信號,因爲未決信號集2號信號爲1,都被忽略,當函數執行完畢,則阻塞信號集置0,信號b經過,因此只執行兩次函數。

測試代碼:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sig_func(int n)
{
    int flag = 3;
    for(int i = 0; i < 3;i++)
    {
        printf("---flag:%d-----\n",flag);
        flag--;
        sleep(1);
    }
}
int main()
{
    struct sigaction act,oldact;
    act.sa_handler = sig_func;
    act.sa_flags  = 0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGINT,&act,&oldact);
    while(1);
}

結果:

alarm返回沒定時夠的秒數(定時10s可是在過了2s後,程序被終端則返回8s)

 時序競態:原子功能,信號之間用全局資源用可重入函數

測試代碼:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void alm(int n)
{}
unsigned int mysleep(unsigned int seconds)
{
    //由於時間資源的競爭,致使程序引起災難性後果,時序竟態
    int reval;
    sigset_t set,oldset;
    sigemptyset(&set);
    sigaddset(&set,SIGALRM);
    sigprocmask(SIG_BLOCK,&set,&oldset);
    sigemptyset(&oldset);
    signal(SIGALRM,alm);
    reval = alarm(seconds);
    if(reval == -1)
        perror("Alarm call Failed:");
    //pause();
    sigsuspend(&oldset);
}
int main()
{
    while(1)
    {
        printf("Two seconds..\n");
        mysleep(2);
    }
}

用pause函數存在的問題:當計時器開始計數,但時間片沒有了,去執行其餘進程,過程當中發回SIGALRM,當時間片輪轉回來時,會先處理信號,而後再執行pause(),這樣線程就會永遠不被喚醒。

int pause(void)
       使調用進程掛起,直到有信號遞達,若是遞達信號是忽略,則繼續掛起
int sigsuspend(const sigset_t *mask)       1.以經過指定mask來臨時解除對某個信號的屏蔽,       2.而後掛起等待,       3.當被信號喚醒sigsuspend返回時,進程的信號屏蔽字恢復爲原來的值

相關文章
相關標籤/搜索