码迷,mamicode.com
首页 > 系统相关 > 详细

Linux System Programming 学习笔记(十) 信号

时间:2014-05-30 21:49:40      阅读:360      评论:0      收藏:0      [点我收藏+]

标签:c   style   class   blog   code   java   

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

 

bubuko.com,布布扣
#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!\n");
        else if (signo == SIGTERM)
                printf ("Caught SIGTERM!\n");
        else {
                /* this should never happen */
                fprintf (stderr, "Unexpected signal!\n");
                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!\n");
                exit (EXIT_FAILURE);
        }
        /*
         * Register signal_handler as our signal handler
         * for SIGTERM.
         */
        if (signal (SIGTERM, signal_handler) == SIG_ERR) {
                fprintf (stderr, "Cannot handle SIGTERM!\n");
                exit (EXIT_FAILURE);
        }
        /* Reset SIGPROF‘s behavior to the default. */
        if (signal (SIGPROF, SIG_DFL) == SIG_ERR) {
                fprintf (stderr, "Cannot reset SIGPROF!\n");
                exit (EXIT_FAILURE);
        }
        /* Ignore SIGHUP. */
        if (signal (SIGHUP, SIG_IGN) == SIG_ERR) {
                fprintf (stderr, "Cannot ignore SIGHUP!\n");
                exit (EXIT_FAILURE);
        }
        for (;;)
                pause ();
        return 0;
}
bubuko.com,布布扣

 

bubuko.com,布布扣
#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 */
};
bubuko.com,布布扣
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
 
信号行为的继承:
bubuko.com,布布扣 
 
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,并且不能调用 不可重入函数
 

Linux System Programming 学习笔记(十) 信号,布布扣,bubuko.com

Linux System Programming 学习笔记(十) 信号

标签:c   style   class   blog   code   java   

原文地址:http://www.cnblogs.com/wwwjieo0/p/3760066.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!