信号(基本概念 signal函数)

基本概念

信号是软件类型的中断,但不是中断,中断是指由外部设备通过硬件请求的方式产生的中断,信号是是由CPU运行程序错误或执行内部程序调用对于异步事件的响应。

信号与中断的区别

相同点:

(1)采用了相同的异步通信方式;

(2)当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;

(3)都在处理完毕后返回到原来的断点;

(4)对信号或中断都可进行屏蔽。

不同点:

(1)中断有优先级,而信号没有优先级,所有的信号都是平等的;

(2)信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;

(3)中断响应是及时的,而信号响应通常都有较大的时间延迟

常用信号

进程对信号的三种处理方式

(1)忽略信号 

不采取任何操作、有两个信号不能被忽略:SIGKILL(9号信号)和SIGSTOP。

(2)捕获并处理信号  

内核中断正在执行的代码,转去执行先前注册过的处理程序。

(3)执行默认操作  

默认操作通常是终止进程,这取决于被发送的信号。

函数signal

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
RETURN VALUE
signal()  returns  the previous value of the signal handler, or SIG_ERR on error.  In the event of an error,  errno  is  set  to  indicate  the cause.

signal是一个带signum和handler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出

handler这个函数必须有一个int类型的参数(即接收到的信号状态码),它本身的类型是void

handler也可以是下面两个特殊值:SIG_IGN  (屏蔽该信号) ,SIG_DFL( 恢复默认行为)

#define SIG_ERR (void (*)())-1
#define SIG_DEL (void (*)())0
#define SIG_IGN (void (*)())1

signal信号捕获函数

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
static void usr(int num)
{
    printf("the signal number is %d\n",num);
    if(num==SIGINT)
    {
        printf("SIGINT signal occured\n");
        exit(0);
    }
}
int main()
{
    if(signal(SIGINT,usr)==SIG_ERR)
    {
        printf("can't catch SIGINT signal\n");
    }
    for(;;)
    {
        pause();
    }
    return 0;
}

屏蔽信号函数

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
static void usr(int num)
{
    printf("the signal number is %d\n",num);
    if(num==SIGINT)
    {
        printf("SIGINT signal occured\n");
        exit(0);
    }
}
int main()
{
    if(signal(SIGINT,SIG_IGN)==SIG_IGN)
    {
        signal(SIGINT,usr);
    }
    for(;;)
    {
        pause();
    }
    return 0;
}

signal函数恢复默认行为

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
void usr(int num)
{
    printf("signal num is %d\n",num);
    if(num==SIGINT)
    {
        printf("SIGINT signal occured!\n");
    }
}
int main()
{
    char ch;
    if(signal(SIGINT,usr)==SIG_ERR)
    {
        printf("error!");
    }
    while((ch=getchar())!='e')
    {
        pause();
    }
    signal(SIGINT,SIG_DFL);
    for(;;)
    {
        pause();
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_33506160/article/details/80341419