信号#1

2019-09-26  本文已影响0人  无无吴

信号的概念

取决于进程的要求,内核对Signal信号有如下三种行为:

  1. 忽略信号
  2. 抓住这个信号并且对这个信号进行处理
  3. 采取默认行为

信号标识符Signal Identifiers

Signals#1
Signals#2

在Linux中, SIGINFO = SIGPWR | SIGIOT = SIGABRT | SIGPOLL = SIGLOST = SIGIO

基本信号管理

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

还可以使用signal()指示内核忽略当前进程的给定信号,或者将信号重置为默认行为。这是使用处理。可以通过使用特殊的值给予handler参数来是实现。

等待一个或任意信号

可用于调试和编写演示代码片段,POSIX定义的pause()系统调用将进程置于睡眠状态,直到接收到处理或终止进程的信号为止 :

#include <unistd.h>
int pause(void);

pause()只在接收到信号时返回,在这种情况下信号被处理,而pause()返回−1并将errno设置为EINTR。如果内核引发一个被忽略的信号,进程就不会唤醒。

Examples

//test SIGINT
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
/* handler for SIGINT */
static void sigint_handler (int signo) {
  /*
   * Technically, you shouldn't use printf() in a
   * signal handler, but it isn't the end of the
   * world. I'll discuss why in the section
   * "Reentrancy."
   */
    printf ("Caught SIGINT!\n");
    exit (EXIT_SUCCESS);
}
int main (void) {
    /*
     * Register sigint_handler as our signal handler
     * for SIGINT.
     */
     if (signal (SIGINT, sigint_handler) == SIG_ERR) {
     fprintf (stderr, "Cannot handle SIGINT!\n");
    exit (EXIT_FAILURE);
}
for (;;)
    pause ();
return 0;
 }
测试结果
#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; 
}

执行和继承

子进程继承父进程的信号操作(ignore, default, handle)。


signal
/* handle SIGINT, but only if it isn't ignored */
if (signal (SIGINT, SIG_IGN) != SIG_IGN) {
    if (signal (SIGINT, sigint_handler) == SIG_ERR)
        fprintf (stderr, "Failed to handle SIGINT!\n");
}
/* handle SIGQUIT, but only if it isn't ignored */
if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) {
    if (signal (SIGQUIT, sigquit_handler) == SIG_ERR)
        fprintf (stderr, "Failed to handle SIGQUIT!\n");
}

Mapping Signal Numbers to Strings

#define _GNU_SOURCE
#include <string.h>
char * strsignal (int signo);
static void signal_handler (int signo) {
    printf ("Caught %s\n", sys_siglist[signo]);
}
上一篇 下一篇

猜你喜欢

热点阅读