C/C++ 進程間通訊 signal

signal.h是C標準函數庫中的信號處理部分, 定義了程序執行時如何處理不一樣的信號。信號用做進程間通訊, 報告異常行爲(如除零)、用戶的一些按鍵組合(如同時按下Ctrl與C鍵,產生信號SIGINT)。linux

C++中的對應頭文件是csignalwindows

/**linux下signum.h**/
/* Signals.  */
#define    SIGHUP        1    /* Hangup (POSIX).  */
#define    SIGINT        2    /* Interrupt (ANSI).  */
#define    SIGQUIT        3    /* Quit (POSIX).  */
#define    SIGILL        4    /* Illegal instruction (ANSI).  */
#define    SIGTRAP        5    /* Trace trap (POSIX).  */
#define    SIGABRT        6    /* Abort (ANSI).  */
#define    SIGIOT        6    /* IOT trap (4.2 BSD).  */
#define    SIGBUS        7    /* BUS error (4.2 BSD).  */
#define    SIGFPE        8    /* Floating-point exception (ANSI).  */
#define    SIGKILL        9    /* Kill, unblockable (POSIX).  */
#define    SIGUSR1        10    /* User-defined signal 1 (POSIX).  */
#define    SIGSEGV        11    /* Segmentation violation (ANSI).  */
#define    SIGUSR2        12    /* User-defined signal 2 (POSIX).  */
#define    SIGPIPE        13    /* Broken pipe (POSIX).  */
#define    SIGALRM        14    /* Alarm clock (POSIX).  */
#define    SIGTERM        15    /* Termination (ANSI).  */
#define    SIGSTKFLT    16    /* Stack fault.  */
#define    SIGCLD        SIGCHLD    /* Same as SIGCHLD (System V).  */
#define    SIGCHLD        17    /* Child status has changed (POSIX).  */
#define    SIGCONT        18    /* Continue (POSIX).  */
#define    SIGSTOP        19    /* Stop, unblockable (POSIX).  */
#define    SIGTSTP        20    /* Keyboard stop (POSIX).  */
#define    SIGTTIN        21    /* Background read from tty (POSIX).  */
#define    SIGTTOU        22    /* Background write to tty (POSIX).  */
#define    SIGURG        23    /* Urgent condition on socket (4.2 BSD).  */
#define    SIGXCPU        24    /* CPU limit exceeded (4.2 BSD).  */
#define    SIGXFSZ        25    /* File size limit exceeded (4.2 BSD).  */
#define    SIGVTALRM    26    /* Virtual alarm clock (4.2 BSD).  */
#define    SIGPROF        27    /* Profiling alarm clock (4.2 BSD).  */
#define    SIGWINCH    28    /* Window size change (4.3 BSD, Sun).  */
#define    SIGPOLL        SIGIO    /* Pollable event occurred (System V).  */
#define    SIGIO        29    /* I/O now possible (4.2 BSD).  */
#define    SIGPWR        30    /* Power failure restart (System V).  */
#define SIGSYS        31    /* Bad system call.  */
#define SIGUNUSED    31

/**windows下gcc signal.h**/
#define    SIGINT        2    /* Interactive attention */
#define    SIGILL        4    /* Illegal instruction */
#define    SIGFPE        8    /* Floating point error */
#define    SIGSEGV        11    /* Segmentation violation */
#define    SIGTERM        15    /* Termination request */
#define SIGBREAK    21    /* Control-break */
#define    SIGABRT        22    /* Abnormal termination (abort) */

#define NSIG 23     /* maximum signal number + 1 */
View Code
static void sig_handler(int signum){
    switch(signum){
        case SIGUSR1:
           cout<<"SIGUSR1";
           stop();
           break;
        case SIGUSR2:
           cout<<"SIGUSR2";
           stop();
           break;
        case SIGTERM:
           cout<<"SIGTERM";
           stop();
           break;
    }  
    exit(0);
}

int main(){
    signal(SIGUSR1,sig_handler);
    signal(SIGUSR2,sig_handler);
    signal(SIGTERM,sig_handler);
    return 0;
}

庫函數raise()或者系統調用kill()能夠產生信號。raise()發送一個信號給當前進程,kill()發送一個信號給特定進程。異步

除了兩個信號SIGKILL與SIGSTOP不能被捕獲(caught)、阻塞(blocked)或者忽略,其它的信號均可以指定處理函數(handler)。一個信號的處理函數在信號到達時,被目標環境調用。目標環境掛起當前進程的執行,直到信號處理函數返回或者調用了longjmp()。爲了最大的兼容性,異步信號處理只應:socket

  • 成功調用了signal()指定的函數;
  • 給類型爲sig_atomic_t的對象賦值;
  • 把控制返回給它的調用者。

若是信號報告了進程的錯誤,信號處理函數應該調用abort()exit()longjmp()ide

kill():

頭文件:#include <sys/types.h>   #include <signal.h>

定義函數:int kill(pid_t pid, int sig);

函數說明:kill()能夠用來送參數sig 指定的信號給參數pid 指定的進程。參數pid 有幾種狀況:
一、pid>0 將信號傳給進程識別碼爲pid 的進程.
二、pid=0 將信號傳給和目前進程相同進程組的全部進程
三、pid=-1 將信號廣播傳送給系統內全部的進程
四、pid<0 將信號傳給進程組識別碼爲pid 絕對值的全部進程參數 sig 表明的信號編號可參考附錄D

返回值:執行成功則返回0, 若是有錯誤則返回-1.

錯誤代碼:
一、EINVAL 參數sig 不合法
二、ESRCH 參數pid 所指定的進程或進程組不存在
三、EPERM 權限不夠沒法傳送信號給指定進程

範例函數

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
main()
{
    pid_t pid;
    int status;
    if(!(pid= fork()))
    {
        printf("Hi I am child process!\n");
        sleep(10);
        return;
    }
    else
    {
        printf("send signal to child process (%d) \n", pid);
        sleep(1);
        kill(pid, SIGABRT);
        wait(&status);
        if(WIFSIGNALED(status))
            printf("chile process receive signal %d\n", WTERMSIG(status));
    }
}

執行:
sen signal to child process(3170) Hi I am child process! child process receive
signal 6
View Code
相關文章
相關標籤/搜索