信号(一)

概念:

系统在响应某些状况而产生的事件,进程在接收到信号后采取相应的动作。

产生信号的方式:

1.键盘事件

Ctrl + c → 2) SIGINT(终止/中断) "INT" ----Interrupt

Ctrl + z → 20) SIGTSTP(暂停/停止) "T" ----Terminal 终端。

​ Ctrl +   → 3) SIGQUIT(退出)

2.硬件异常产生指令

  •  除0操作 → 8) SIGFPE (浮点数例外) "F" -----float 浮点数。
  • 非法访问内存 → 11) SIGSEGV (段错误)
  • 总线错误 → 7) SIGBUS

3.函数/命令产生信号

kill命令产生信号:kill -SIGKILL pid

kill函数:给指定进程发送指定信号

 

在linux中,输入 kill -l,会出现linux系统中信号的类别:

这就是信号的全部种类。其中1-31是普通信号,34以后是实时信号。

信号的处理方式:

    1. 忽略(SIGKILL和SIGSTOP这两个信号是不能被忽略的,因为他)
    2. 执行默认处理方式(缺省处理方式,由系统定义处理方式 可通过 man 7 signal查看具体)
    3. 捕捉并处理。(方式由用户自定义)

信号分类:

    1. 不可靠信号:(1-31)
      Linux信号处理继承来自基于UNIX,早期的UNIX当信号处理函数执行完毕后,该信号恢复成缺省处理动作。虽然Linux已改进,但是继承开发的东西太多了,已经不可能把该恢复默认成缺省动作删除了。

信号不排队。在某一时刻,几个信号传递过来的时候并没有处理完,导致了某些信号的丢失。

    1. 可靠信号:(34-64):不会出现信号丢失。

注册信号:

void (*signal(int signum, void(*pf)(int)))(int);
void (*pf)(int);        //自定义的函数处理

发送信号:

kill(pid_t pid, int signum);

pid_t说明:

    • pid > 0:将信号传给进程识别码未pid的进程。
    • pid == 0:将进程传给和目前进程相同进程组的所有进程
    • pid == -1:将信号广播传送给系统内所有进程。
    • pid < 0:将信号传给进程组识别码为pid绝对值的所有进程。

singnum代表信号编号,参照上方kill -l显示的信号

返回值:

执行成功则返回0,失败返回-1。

错误码:

EINVAG:参数sig不合法。

ESRCH:参数pid所指定的进程或进程组不存在。

EPERM:权限不够无法传送给指定进程。

实例一:

注册和发送信号:

/*register.c*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>

void handler(int s)
{
    printf("recv %d
", s);
    exit(0);
}

int main()
{
    signal(SIGUSR1, handler);
    pid_t pid;
    pid = fork();
    if (pid == 0)
    {
        sleep(3);
        kill(getppid(), SIGUSR1); //getppid()获取父进程进程号
    }
    else
    {
        for( ; ;) 
        {
            printf("1");
            fflush(stdout);
            sleep(1);
        }
    }
    return 0;
}

运行结果:

ubuntu@ubuntu:~/wangqinghe/signal$ ./register

1111recv 10

原文地址:https://www.cnblogs.com/wanghao-boke/p/12116712.html