zoukankan      html  css  js  c++  java
  • Linux System Programming 学习笔记(十) 信号

    1. 信号是软中断,提供处理异步事件的机制

    异步事件可以是来源于系统外部(例如用户输入Ctrl-C)也可以来源于系统内(例如除0)
     
    内核使用以下三种方法之一来处理信号:
    (1) 忽略该信号SIGKILL和SIGSTOP不能被忽略
    (2) 捕捉并且处理该信号。The kernel will suspend execution of the process’s current code path and jump to a previously registered function.
    SIGKILL和SIGSTOP不能被捕捉
    (2) 执行默认操作
     
    SIGCHLD:进程终止时,内核向其父进程发送SIGCHLD信号,默认是忽略,如果父进程需要子进程终止信息,而需要显式处理,通常是调用wait函数
    SIGINT:用户输入中断字符 Ctrl-C
    SIGKILL,SIGSTOP:kill系统调用发出的信号,不能被忽略,不能被捕捉,结果总是终止进程
    SIGSEGV:段错误
     

    2. 基本的信号管理

    #include <signal.h>
    typedef void (*sighandler_t)(int);
    sighandler_t signal (int signo, sighandler_t handler);

    signal() removes the current action taken on receipt of the signal signo and instead handles the signal with the signal handler specified by handler

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    /* handler for SIGINT and SIGTERM */
    static void signal_handler (int signo)
    {
            if (signo == SIGINT)
                    printf ("Caught SIGINT!
    ");
            else if (signo == SIGTERM)
                    printf ("Caught SIGTERM!
    ");
            else {
                    /* this should never happen */
                    fprintf (stderr, "Unexpected signal!
    ");
                    exit (EXIT_FAILURE);
            }
            exit (EXIT_SUCCESS);
    }
    int main (void)
    {
            /*
             * Register signal_handler as our signal handler
             * for SIGINT.
             */
            if (signal (SIGINT, signal_handler) == SIG_ERR) {
                    fprintf (stderr, "Cannot handle SIGINT!
    ");
                    exit (EXIT_FAILURE);
            }
            /*
             * Register signal_handler as our signal handler
             * for SIGTERM.
             */
            if (signal (SIGTERM, signal_handler) == SIG_ERR) {
                    fprintf (stderr, "Cannot handle SIGTERM!
    ");
                    exit (EXIT_FAILURE);
            }
            /* Reset SIGPROF's behavior to the default. */
            if (signal (SIGPROF, SIG_DFL) == SIG_ERR) {
                    fprintf (stderr, "Cannot reset SIGPROF!
    ");
                    exit (EXIT_FAILURE);
            }
            /* Ignore SIGHUP. */
            if (signal (SIGHUP, SIG_IGN) == SIG_ERR) {
                    fprintf (stderr, "Cannot ignore SIGHUP!
    ");
                    exit (EXIT_FAILURE);
            }
            for (;;)
                    pause ();
            return 0;
    }
    #include <signal.h>
    int sigaction (int signo, const struct sigaction *act, struct sigaction *oldact);
    
    struct sigaction {
            void (*sa_handler)(int);   /* signal handler or action */
            void (*sa_sigaction)(int, siginfo_t *, void *);
            sigset_t sa_mask;          /* signals to block */
            int sa_flags;              /* flags */
            void (*sa_restorer)(void); /* obsolete and non-POSIX */
    };
    sigaction() changes the behavior of the signal identified by signo, signo不能为SIGKILL和SIGSTOP
    If act is not NULL, the system call changes the current behavior of the signal as specified by act
     
    信号行为的继承:
     
     

    3. 发送信号

     
    int ret;
    ret = kill (1722, SIGHUP);
    if (ret)
            perror ("kill");
    上述代码表示:向pid为1722的进程发送SIGHUP信号
    上述代码与以下shell语句等同:
    $ kill -HUP 1722
    /*  a simple way for a process to send a signal to itself */
    #include <signal.h>
    int raise (int signo);
    raise (signo);

    等同于:

    kill (getpid (), signo);

    4. 可重入

    A reentrant function is a function that is safe to call from within itself (or concurrently, from another thread in the same process).
    为了确保可重入,函数不能操作static变量,只能操作 stack-allocated data,并且不能调用 不可重入函数
     
  • 相关阅读:
    李开复给中国学生的第一封信
    vc++学习篇(三)——预处理命令之条件编译(#ifdef,#else,#endif,#if等)
    高级程序员考试时间安排和参考书推荐
    vc++学习篇(四)—— 指针
    程序员应具备的素质
    Word 2003 长篇文档排版技巧(二)
    Google 技巧集锦
    给中国学生的第二封信
    修复mysql表
    社保相关
  • 原文地址:https://www.cnblogs.com/wwwjieo0/p/3760066.html
Copyright © 2011-2022 走看看