linux:信号的初识

标签:
14人阅读 评论(0) 收藏 举报
分类:

一.信号是什么

在生活中,我们也可以能会见到各种各样的信号,比如你正在上课,突然铃声一响,那就意味着下课了,铃声就是一种信号,我们大家都约定好的,只要铃声一响那就代表下课了
在linux中,比如你正在执行一个程序,你突然按下Ctrl -c,程序就会结束执行,这是因为给操作系统发了一个2号信号SIGINT,此信号的作用是中止进程,CPU正在执行代码,收到此信号后就会结束进程,CPU具体处理信号的流程请往下看

二.都有哪些信号?

命令:kill -l //可以查看在操作系统中都有哪些信号

这里写图片描述
由图来看:共有62种信号,因为序号31和34之间少了32和33,所以一共62种信号
1-31是普通信号

此类信号是不可靠信号,不支持排队,所以可能会造成数据丢失

34-64是实时信号

此类信号是可靠信号,支持排队,故不会造成数据丢失

三.常见的信号

(1)2--->SIGINT--->终止进程(用于通知前台进程组终止进程)
                    Ctrl -c产生

(2)3--->SIGQUIT--->和SIGINT类似,进程终止,但是此信号会产生core文件
                    Ctrl  -\产生

(3)6--->SIGABRT--->调用abort函数生成的信号
(4)8--->SIGFPE--->在发生致命的算术运算错误时发出,不仅包括浮点运算错
                   误,还包括溢出及除数为0等错误
(5) 9--->SIGKILL--->杀死进程(本信号不能被阻塞、处理和忽略)
 (6)11--->SIGSEGV--->试图访问未分配给自己的内存或者试图往没有写权限
                     的内存地址写数据
    ps:段错误就会发此信号
 (7)13--->SIGPIPE--->管道读端关闭尝试写(管道破裂,此信号通常在进程
                      间通信产生)
 (8)14--->SIGALRM--->时钟定时信号,计算的是实际的时间或时钟时间
                     alarm函数使用的就是此信号
 (9)15--->SIGTERM--->程序结束信号,与SIGKILL不同的是该信号可以被阻塞
                     和处理,通常用来要求程序自己正常退出
ps: 此信号不会被立即处理,而是等进程继续运行之前才会处理,
     默认处理动作是终止进程                   
 (10)17--->SIGCHLD--->子进程结束,父进程会收到这个信号
 (11)18---->SIGCONT---->让一个停止(stopped)的进程继续执行,本信号
                         不能被阻塞(即就是继续运行停止的进程)
 (12)20--->SIGTSTP--->停止进程的运行,此信号不能被处理和忽略
                       Ctrl -z产生
 (13)21---->SIGTTIN---->当后台作业要从用户终端读取数据时,那该作业中
                      的所有进程都会收到此信号,此信号会让进程停止执行

 (14)29--->SIGIO--->文件描述符准备就绪,可以开始进行输入/输出操作

中止进程的信号:SIGINT/SIGQUIT
程序不可捕获、阻塞或忽略的信号:SIGKILL
默认会导致进程流产的信号:SIGABRT 、SIGFPE 、SIGQUIT
默认会导致进程退出的信号:SIGALRM 、SIGKILL 、SIGPIPE、 SIGTERM
默认会导致进程停止的信号:SIGTSTP、SIGTTIN

四.信号的产生方式

1.由用户终端按键产生
  例如当一个正在运行的时候,用户可以输入Ctrl -c来停止进程的运行,Ctrl -z2号信号SIGINT,作用是停止进程的运行

2.硬件异常产生
此种信号是由硬件检测到并通知内核,然后内核向当前进程发送适当的信号
(1)当前进程执行了除以0的操作,CPU的运算单元会产生异常,内核会给此进程发送SIGFPE,即就是8号信号,该信号的作用是在发生致命的算术运算错误时产生,包括浮点运算错误、溢出、除数为0等错误
(2)MMU异常,当前进程访问了非法的内存(虚拟地址空间不存在或者是虚拟地址空间没有权限访问),MMU会产生异常,并把此异常报给给操作系统内核,操作系统会给此进程发送11号信号即就是SIGSEGV,该信号的作用就是当非法访问内存时,就会此信号

3.由调用系统函数时产生

4.由软件条件产生

第一种:由用户终端按键产生

SIGINT的默认处理动作是中止进程,SIGQUIT的默认处理动作也是中止进程并产生Core Dump文件,SIGINT由Ctrl -z产生,SIGQUIT由Ctrl -\产生

1.Core Dump是什么?

    当一个进程要异常终止时,可以选择把进程的用户空间内存数据保存到磁盘上,文件名通常是Core Dump
    Core Dump文件(核心转储文件)就是相当于一个文件在要死亡时的临终遗言,他会把自自己的遗言都封装在这个文件里,比如发生车祸时,我们需要来保护车祸现场,以防止以后的需要,那Core Dump文件相当于车祸现场,是用来保存在进程异常终止时,进程在用户空间中的内存数据

2.怎样产生Core Dump文件?

一个进程允许产生多大的Core Dump文件取决于进程的Resource Limit(这个信息保存在PCB中)
注意:是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全

3.相关命令

ulimit -c+文件大小 //umilit -c可以创建core文件并且指定此文件的大小
ulimit -a //查看是否成功创建core文件

这里写图片描述
这里写图片描述
执行一个死循环程序,然后按下Ctrl -\ ,来中止进程,并且产生core文件
代码:

#include<stdio.h>
int main()
{
    while(1)
    {
        printf("pid is =%d\n",getpid());
        sleep(1);
    }
    return 0;
}

结果:

这里写图片描述

第二种:通过系统调用系统函数产生

1.kill函数

功能:给指定的进程发送指定的信号

头文件:#include<signal.h>

int kill(pid_t pid,int signo);
参数说明:
pid--->进程ID,给那个进程发送信号
signo--->发送几号信号

返回值:成功返回0,失败返回-1

示例
创建了两个进程,通过kill()来中止指定的进程

#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
int count=0;
int main()
{
    pid_t pid;
    pid=fork();
    if(pid<0)
    {
        perror("fork");
        exit(1);
    }
    while(1){
        if(pid==0){
            //子进程
            printf("I am child process.\n");
            sleep(1);
        }
        else{
            count++;
            if(count>5)
                kill(pid,SIGKILL);//循环6次后,中止子进程
            printf("I am father process.\n");
            sleep(1);
        }
    }
    return 0;
}

运行结果:
这里写图片描述

2.raise函数

功能:给当前的进程发送指定的信号
头文件:#include<signal.h>
int raise(int signo);
返回值:成功返回0,失败返回-1

示例
(1)给当前进程发送9号信号,杀死进程

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
int main()
{
    int count=0;
    pid_t pid=getpid();
    while(1)
    {
        if(count>10)
            raise(SIGKILL);
        printf("pid is %d\n",pid);
        count++;
        sleep(1);
    }
    return 0;
}

运行结果:
这里写图片描述
(2)给当前进程发送11号信号

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
int main()
{
    int count=0;
    pid_t pid=getpid();
    while(1)
    {
        if(count>10)
            raise(11);
        printf("pid is %d\n",pid);
        count++;
        sleep(1);
    }
    return 0;
}

运行结果:
这里写图片描述
11号信号的作用是,如果非法访问内存,就会发此信号,即就是段错误时发送的信号

3.abort函数

功能:使当前进程接收到信号而异常终止
头文件:#include<signal.h>
int abort(void);
无返回值,可参考exit()

第三种:由硬件异常产生

(1)除数为0

#include<stdio.h>
#include<stdlib.h>
int main()
{
 int a=0;
 int b=20;
 int c=b/a;
 printf("c=%d\n",c);
 return 0;
 }

运行结果:
这里写图片描述
除数为0是致命的算术运算错误,操作系统会给此进程发送8号信号—>SIGFPE,此信号的作用是在发生致命的算术运算错误,比如除数为0、溢出、浮点运算错误,此时操作系统就会给进程发送8号信号

(2)非法访问内存

#include<stdio.h>
#include<stdlib.h>
int main()
{
 int*p=NULL;
 *p=100;
 printf("%d\n",*p);
 return 0;
 }

运行结果:
这里写图片描述
非法访问内存,操作系统会给进程发送11号信号—>SIGSEGV,此信号的作用是当访问没有权限的虚拟地址空间或者虚拟地址空间不存在时,就会 产生此种信号

ps:解引用空指针的后果:
1.直接使程序结束;
2.进程会收到信号结束;
3.产生MMU异常
MMU发现错误的虚拟地址空间或者此虚拟地址空间没有权限访问,就会报告给操作系统内核,然后操作系统会给此进程发送11号信号

第四种:由软件条件产生

alarm()

功能:此函数可以设置一个闹钟,也就是告诉内核在seconds秒之后给进程发
     送SIGALARM信号,该信号的默认处理动作是终止当前进程

返回值:0或者以前设定的闹钟时间剩下的秒数
unsigned int alarm(unsigned int seconds)

示例
使用alarm函数设置一个闹钟,闹钟的时间到了之后,就会结束进程


#include<stdio.h>
int main()
{
    alarm(2);
    while(1)
    {
        printf("hello\n");
        sleep(1);
    }
    return 0;
}

运行结果:
这里写图片描述
结果解析:本来应该是死循环的输出hello,但使用alarm函数给进程设置了一个闹钟,时间到就会结束进程

五.信号的处理方式

1.忽略
2.执行该信号的默认处理操作
3.自定义,即就是提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行此函数,这种方式称为捕捉信号

查看评论

linux中的信号-3.5.linux应用编程和网络编程第5部分

-
  • 1970年01月01日 08:00

【Linux基础】初识Linux

1:什么是Linuxlinux是类Unix操作系统。 FSF,GNU。2:什么是嵌入式OS以应用为中心,以计算机技术为基础,软硬件可裁剪。专用的计算机系统。3:linux发行版本Ubuntu,...
  • wr132
  • wr132
  • 2017-03-13 18:08:44
  • 222

初识kali-linux

在虚拟机里安装了专用安全测试工具,kali linux,         vm及其安装步骤很简单,kali是debain的一个linux发型版本,里面包含很多安全测试工具,既然是工具,你懂的,既是盾也...
  • anttu
  • anttu
  • 2017-07-15 16:57:10
  • 504

Linux基础知识第一期《初识linux》

温馨提示:以下博文是我以前听课留下的笔记,现在共享给大家,写的不好,不过适合初学者的一份完整的linux笔记,可能会有一些瑕疵,欢迎给我留言,进行交流。个人的建议是配合视频一起看,这样有助于指令的记忆...
  • qq_29557995
  • qq_29557995
  • 2016-01-20 18:45:30
  • 335

菜鸟初识linux笔记一

发展历史    UNIX (1)1965年,美国的麻省理工学院(MIT)、通用电气公司(GE)及贝尔实验室(AT&A)三家联合开发Multics,开发一种交互式的具有多道处理能力的分时操作系统,但...
  • php_897721669
  • php_897721669
  • 2011-12-06 16:07:55
  • 357

Linux进程初识

随便说说      最近在实习, 公司里面用的电脑系统里面是ubuntu, 之前在学校里也用装过这个系统, 当时也就是试试玩着, 简单地熟悉里面的几个命令而已(ls,  cd , mkdir ...
  • heiyouhei123
  • heiyouhei123
  • 2014-12-28 15:38:14
  • 557

linux进程初识

什么是进程?1.进程是已启动的可执行程序的运行实例,进程由以下几部分组成:a.已分配内存的地址空间b.安全属性,包括所有权凭据和特权c.程序代码的一个或多个执行线程d.进程状态e.进程需要一个用户身份...
  • lingtian213
  • lingtian213
  • 2017-08-07 22:26:10
  • 83

linux学习第二篇:初识linux简单命令

客户端Xshell 认识linux客户端Xshell 5 首先,安装Xshell 5通过主机IP连接linux服务器,通过ifconfig查询ip地址 打开客户端Xshell,连接linux输入用户...
  • yuchao2015
  • yuchao2015
  • 2016-08-05 21:41:17
  • 984

Linux信号列表

我们运行如下命令,可看到Linux支持的信号列表:$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTR...
  • baobao8505
  • baobao8505
  • 2006-08-25 08:35:00
  • 39211

Linux概述,包括 安装、启动和关闭Linux

  • 2009年11月05日 11:46
  • 538KB
  • 下载
    个人资料
    持之以恒
    等级:
    访问量: 2万+
    积分: 1153
    排名: 4万+
    文章分类
    最新评论