当前位置: 移动技术网 > IT编程>数据库>Mysql > Linux signals理论、C语言捕获信号及处理

Linux signals理论、C语言捕获信号及处理

2018年01月07日  | 移动技术网IT编程  | 我要评论
首先需要知道signals和interrupt是不同的。 signal属于进程通信机制的一种实现方式 (还有的实现为:Pipes、Sockets 其中Sockets又可分为: Syste

首先需要知道signals和interrupt是不同的。
signal属于进程通信机制的一种实现方式
(还有的实现为:Pipes、Sockets
其中Sockets又可分为: System V IPC Mechanisms、Message Queues、Semaphores、Shared Memory)

而具体的不同,别人的回答是:

Interrupts can be viewed as a mean of communication between the CPU and the OS kernel. Signals can be viewed as a mean of communication between the OS kernel and OS processes.

Interrupts may be initiated by the CPU (exceptions -e.g.: divide by zero, page fault), devices (hardware interrupts -e.g.: input available), or by a CPU instruction. They are eventually managed by the CPU, which “interrupts” the current task,and invokes an 0S-kernel provided ISR/interrupt handler

Signals may be initiated by the OS kernel(下面的实例也揭示了这一点), or by a process( kill() ). They are eventually managed by the OS kernel, which delivers them to the target thread/process, invoking either a generic action (ignore, terminate, terminate and dump core) or a process-provided signal handler.

SIGKILL与SIGSTOP是两个唯一不能忽略也不能捕获的信号

C语言捕获信号并处理

第一步:向内核注册

the process has to register a signal handling function to the kernel.

原型是:c void (int sig)

第二步:获得signal handler

To get the signal handler function registered to the kernel, the signal handler function pointer is passed as second argument to the ‘signal’ function

原型是:c void (*signal(int signo, void (*func )(int)))(int);
简单化:c sigfunc *signal(int, sigfunc*);

实例一:简单捕获信号并处理

#include
#include
#include

void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR)
  printf("\ncan't catch SIGINT\n");
  //必须加上死循环(或者用挂起)来让信号能被进程接收
  while(1) 
    sleep(1);
  return 0;
}
//注意,当前终端用ctrl+c模拟,
//需要终止时,另一个终端使用 ps aux查看进程号,然后用 kill -9 进程号
//来杀死

还值得一提的是,这儿用while(1) sleep(1)
比用单纯的while死循环要好,因为直接while可能会消耗cpu的大部分资源,导致电脑很慢。

On a side note, the use of function sleep(1) has a reason behind. This function has been used in the while loop so that while loop executes after some time (ie one second in this case). This becomes important because otherwise an infinite while loop running wildly may consume most of the CPU making the computer very very slow

实例二:自定义信号

#include
#include
#include

void sig_handler(int signo)
{
    if (signo == SIGUSR1)
        printf("received SIGUSR1\n");
    else if (signo == SIGKILL)
        printf("received SIGKILL\n");
    else if (signo == SIGSTOP)
        printf("received SIGSTOP\n");
}

int main(void)
{
    if (signal(SIGUSR1, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGUSR1\n");
    if (signal(SIGKILL, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGKILL\n");
    if (signal(SIGSTOP, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGSTOP\n");
    // A long long wait so that we can easily issue a signal to this process
    while(1) 
        sleep(1);
    return 0;
}

另一个终端运行:

$ kill -USR1 进程号

输出:

$ ./sigfunc

can't catch SIGKILL

can't catch SIGSTOP
received SIGUSR1

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网